Skip to content

Management API Credentials ​

The Management API uses client credentials (client ID and client secret) for secure server-to-server authentication using the OAuth 2.0 Client Credentials flow.

Overview ​

Client credentials are used exclusively for server-to-server authentication to the Management API. These credentials should be treated as highly sensitive and never exposed in client-side code or public repositories.

Getting Your Credentials ​

Manage your keys through the Management API itself, at https://api2.sesamy.com/management/api-keys. The Sesamy dashboard calls these same endpoints.

Create a Key ​

bash
curl -X POST https://api2.sesamy.com/management/api-keys \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Newsroom CMS", "role": "read" }'

Response:

json
{
  "clientId": "apikey_9f2c1d8e4b7a4f1e9c3d5a6b7c8d9e0f",
  "name": "Newsroom CMS",
  "role": "read",
  "scopes": [
    "access-lists:read",
    "bills:read",
    "checkouts:read",
    "contracts:read",
    "domains:read",
    "entitlements:read",
    "products:read",
    "sites:read",
    "stats:views:read",
    "transactions:read",
    "users:read"
  ],
  "createdAt": "2026-09-01T09:12:44.000Z",
  "clientSecret": "k2Jd8sV1pQ7wE4rT6yU9iO0aS3dF5gH8",
  "tokenUrl": "https://acme.token.sesamy.com/oauth/token",
  "audience": "urn:sesamy"
}
FieldTypeDescription
namestringWhat the key is for. Shown in the key list and the only way to tell keys apart
rolestring(Optional) read or full. Defaults to read

The secret is shown once

clientSecret appears in this response and nowhere else. Store it before you close the response. There is no way to read it back, so replacing a lost secret means deleting the key and creating a new one.

API keys use a different token URL to the rest of the platform

Everywhere else in these docs, the token endpoint is the shared https://token.sesamy.com/oauth/token. API keys are the exception. Your key lives on your own tenant, which is addressed as a subdomain, so it authenticates against https://<your-vendor-id>.token.sesamy.com/oauth/token instead. Posting a key to the shared host reaches a different tenant and fails with invalid_client.

Do not build the URL by hand. Use the tokenUrl and audience returned when the key was created.

List Your Keys ​

bash
curl https://api2.sesamy.com/management/api-keys \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Returns every key for your vendor, newest first, without secrets.

Keep Your Credentials Secret

Never commit credentials to version control or expose them in any client-side code. If your credentials are compromised, revoke them immediately and create new ones.

Using Client Credentials - OAuth 2.0 Client Credentials Flow ​

Step 1: Request an Access Token ​

Send a POST request to the token endpoint with your credentials:

bash
curl -X POST https://acme.token.sesamy.com/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "audience=urn:sesamy"

Replace acme with your own vendor id, as returned in tokenUrl when you created the key.

Response:

json
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_in": 86400
}

Step 2: Use the Access Token ​

Include the access token in the Authorization header of your Management API requests:

bash
curl -X GET https://api2.sesamy.com/management/products \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

With SDKs ​

The Sesamy SDK takes a tokenProvider that returns a complete Authorization header, so it works with a key once you have exchanged it for an access token:

typescript
import { management } from '@sesamy/sdk';

const sdk = management({
  baseUrl: 'https://api2.sesamy.com',
  tokenProvider: async () => `Bearer ${await getAccessToken()}`,
  vendorId: 'acme',
});

const products = await sdk.getProducts();

Cache the token inside getAccessToken rather than exchanging your key on every call. See Implement Token Caching.

Management API Permissions ​

A key carries a preset of Management API scopes, chosen with role when you create it. Presets rather than free-form scope lists keep a key's reach predictable and reviewable.

The read Preset ​

Every read scope: access-lists:read, bills:read, checkouts:read, contracts:read, domains:read, entitlements:read, products:read, sites:read, stats:views:read, transactions:read, and users:read.

Use this for anything that only reports, such as a dashboard, a data export, or a reconciliation job.

The full Preset ​

Everything in read, plus access-lists:write, domains:write, links:create, products:write, sites:write, and users:write.

What no key can do

Neither preset can manage team members, portal permissions, or other API keys. Those stay human, session-authenticated actions, so a leaked key cannot be used to grant its holder access that survives the key being revoked.

Requesting Specific Scopes ​

A token carries the scopes you ask for, narrowed to what the key's preset allows. Ask for less than the preset when a job needs less:

bash
curl -X POST https://acme.token.sesamy.com/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET" \
  -d "audience=urn:sesamy" \
  -d "scope=products:read users:read"

Asking for a scope the preset does not include fails the exchange with access_denied. Omit scope to receive the whole preset.

Scope Patterns ​

Scopes follow a resource:action pattern:

  • resource:read - read and retrieve operations
  • resource:write - create, update, and delete operations

Some scopes cover nested resources. access-lists:write includes managing the grants under an access list.

Best Practices ​

1. Store Securely ​

Use environment variables or a secrets management service:

bash
# .env file (never commit this!)
SESAMY_CLIENT_ID=YOUR_CLIENT_ID
SESAMY_CLIENT_SECRET=YOUR_CLIENT_SECRET

2. Implement Token Caching ​

Cache tokens to reduce token endpoint requests.

Revoking Credentials ​

Delete the key by its clientId:

bash
curl -X DELETE https://api2.sesamy.com/management/api-keys/apikey_9f2c1d8e4b7a4f1e9c3d5a6b7c8d9e0f \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Returns 204 No Content. The key can mint no further tokens.

Tokens already minted stay valid

Revoking stops the key from minting new tokens. Access tokens it minted earlier keep working until they expire, so treat a compromise as live until the longest-lived token has expired.

If you suspect a key has been compromised:

  1. Create a replacement key and deploy it
  2. Delete the compromised key
  3. Check your logs for what the key did while it was exposed

Troubleshooting ​

401 Unauthorized ​

If you receive a 401 Unauthorized error:

  1. Verify your client_id and client_secret are correct
  2. Check that the credentials haven't been revoked
  3. Ensure you're using the correct environment (development vs. production)
  4. Verify the Authorization header is properly formatted as Bearer TOKEN

403 Forbidden ​

If you receive a 403 Forbidden error:

  1. Verify your credentials have access to the Management API
  2. Confirm the requested resource is available in your plan
  3. Check your rate limits haven't been exceeded

Invalid Client ​

If you receive an "invalid_client" error:

  1. Verify your client_id and client_secret are correct
  2. Ensure neither value contains extra whitespace
  3. Confirm the application is active in your dashboard

Next Steps ​

  • OAuth 2.0 - Learn about authorization flows for apps and websites
  • JWT Tokens - Understanding and validating access tokens
  • API Reference - Explore available Management API endpoints

Released under the MIT License.