# How to Set Up API Authentication with Access Tokens in Logto: A Complete Guide

> Set up API authentication with access tokens in Logto. Logto's SDK streamlines M2M authentication using OAuth 2.0 and automatically caches and refreshes tokens before expiry for seamless integration.

- Repository: [Logto/logto](https://github.com/logto-io/logto)
- Tags: how-to-guide
- Published: 2026-07-04

---

**Logto implements standard OAuth 2.0 client-credentials flow for machine-to-machine API authentication, automatically caching access tokens and refreshing them 60 seconds before expiry via the `@logto/api` SDK.**

Setting up **API authentication with access tokens in Logto** enables secure server-to-server communication with the Management API. The `logto-io/logto` repository provides a dedicated TypeScript SDK (`@logto/api`) that abstracts the token exchange, caching, and renewal logic. This guide walks through creating machine-to-machine credentials, configuring the SDK, and making authenticated requests using source-accurate implementation details.

## Prerequisites

Install the official Logto API SDK to handle token management and API client instantiation.

```bash
npm install @logto/api

```

## Understanding the OAuth 2.0 Client Credentials Architecture

Logto’s core OIDC provider implements a custom `client_credentials` grant handler located at [`packages/core/src/oidc/grants/client-credentials.ts`](https://github.com/logto-io/logto/blob/main/packages/core/src/oidc/grants/client-credentials.ts). This supports both standard access tokens and organization-scoped tokens for multi-tenant scenarios.

The SDK abstracts this complexity through two primary components:

- **`ClientCredentials` class** ([`packages/api/src/client-credentials.ts`](https://github.com/logto-io/logto/blob/main/packages/api/src/client-credentials.ts)): Manages token requests, validates JSON responses, caches tokens, and handles automatic refresh with a default 60-second leeway before expiry.
- **`createManagementApi` helper**: Wraps the `ClientCredentials` instance to expose a typed `apiClient` for CRUD operations on Logto resources.

When initialized, the SDK posts a URL-encoded request to `/oidc/token` with `grant_type=client_credentials`, retrieves an opaque access token, and stores it in memory for subsequent requests.

## Step 1: Create a Machine-to-Machine Application

Before writing code, configure the credentials in the Logto Console:

1. Navigate to **Applications** and create a new **Machine-to-Machine** application.
2. Grant the application permissions to the **Management API** (select scopes like `all` or specific resource permissions).
3. Copy the generated **client ID** and **client secret**—these authenticate your SDK instance.

## Step 2: Implement the Authentication Flow

Choose the implementation pattern based on your deployment type (Logto Cloud vs. self-hosted).

### Using the Management API SDK with Logto Cloud

For Logto Cloud deployments, provide your tenant ID and M2M credentials to `createManagementApi`. The SDK automatically targets the correct token endpoint and API base URL.

```typescript
import { createManagementApi } from '@logto/api/management';

const { apiClient } = createManagementApi('your-tenant-id', {
  clientId: 'your-client-id',
  clientSecret: 'your-client-secret',
});

// Example: Fetch all users
const response = await apiClient.GET('/api/users');
console.log('Users:', response.data);

```

The `apiClient` automatically injects the `Authorization: Bearer <token>` header using the cached access token from the internal `ClientCredentials` instance.

### Self-Hosted Configuration

For open-source deployments, explicitly define the `baseUrl` and `apiIndicator` to point to your Logto instance.

```typescript
import { createManagementApi } from '@logto/api/management';

const { apiClient } = createManagementApi('default', {
  clientId: 'your-client-id',
  clientSecret: 'your-client-secret',
  baseUrl: 'https://logto.example.com',
  apiIndicator: 'https://logto.example.com/api',
});

// Create an application via Management API
await apiClient.POST('/api/applications', {
  json: { 
    name: 'My App', 
    redirectUris: ['https://app.example.com/callback'] 
  },
});

```

### Direct ClientCredentials Usage

For custom HTTP clients or non-standard implementations, instantiate the `ClientCredentials` class directly from [`packages/api/src/client-credentials.ts`](https://github.com/logto-io/logto/blob/main/packages/api/src/client-credentials.ts).

```typescript
import { ClientCredentials } from '@logto/api/src/client-credentials';

const credentials = new ClientCredentials({
  clientId: 'your-client-id',
  clientSecret: 'your-client-secret',
  tokenEndpoint: 'https://logto.example.com/oidc/token',
});

// Retrieve cached token (fetches new if expired or not present)
const token = await credentials.getAccessToken();

// Use with any HTTP client
await fetch('https://logto.example.com/api/users', {
  headers: { Authorization: `Bearer ${token.value}` },
});

```

The `getAccessToken()` method constructs the token request body as:

```text
grant_type=client_credentials&
client_id=YOUR_CLIENT_ID&
client_secret=YOUR_CLIENT_SECRET

```

Optional parameters like `scope` or `resource` can be passed via the `tokenParams` constructor option.

## How Token Caching and Automatic Refresh Works

The `ClientCredentials` class in [`packages/api/src/client-credentials.ts`](https://github.com/logto-io/logto/blob/main/packages/api/src/client-credentials.ts) implements an in-memory token cache. When `getAccessToken()` is called, the SDK checks the cached token’s expiry timestamp. If the token expires within 60 seconds (the default leeway), the SDK automatically requests a new token before returning the value.

This eliminates race conditions in high-throughput scenarios and ensures API calls never use expired tokens. The SDK handles network errors and OIDC error responses according to RFC 6749 specifications.

## Summary

- **API authentication with access tokens in Logto** relies on the OAuth 2.0 client-credentials flow implemented in [`packages/core/src/oidc/grants/client-credentials.ts`](https://github.com/logto-io/logto/blob/main/packages/core/src/oidc/grants/client-credentials.ts).
- The `@logto/api` SDK provides the `ClientCredentials` class ([`packages/api/src/client-credentials.ts`](https://github.com/logto-io/logto/blob/main/packages/api/src/client-credentials.ts)) to handle token acquisition, caching, and automatic refresh with a 60-second leeway.
- Use `createManagementApi` for typed Management API access, or instantiate `ClientCredentials` directly for custom HTTP implementations.
- Always send access tokens in the `Authorization: Bearer <token>` header when calling Logto Management API endpoints.

## Frequently Asked Questions

### What is the default token expiry leeway in the Logto SDK?

The `ClientCredentials` class refreshes tokens 60 seconds before their actual expiry by default. This prevents authentication failures due to clock skew or network latency during request transmission.

### Can I use the access token with custom HTTP clients instead of the SDK?

Yes. While the `createManagementApi` helper provides convenient typed methods, you can extract the raw token via `credentials.getAccessToken()` from the `ClientCredentials` class and use it with `fetch`, `axios`, or any HTTP library by setting the `Authorization: Bearer <token>` header manually.

### Does Logto support organization-scoped access tokens for the Management API?

Yes. According to the implementation in [`packages/core/src/oidc/grants/client-credentials.ts`](https://github.com/logto-io/logto/blob/main/packages/core/src/oidc/grants/client-credentials.ts), Logto extends the standard OAuth 2.0 client-credentials grant to support organization-scoped tokens. Pass the `organization_id` parameter via `tokenParams` when constructing the `ClientCredentials` instance to receive tokens scoped to specific organizations.

### Where are the M2M application credentials stored in the Logto system?

The client ID and client secret are generated when you create a Machine-to-Machine application in the Logto Console. These credentials are stored in Logto's database and validated against the OIDC token endpoint at `/oidc/token` when the SDK requests an access token.