Authenticate with API keys
Authenticate Platform API requests with an X-Api-Key header, or a Console session on session-or-api-key routes, and store the secret when you create it.
Overview
An API key authenticates a script, backend service, or other direct integration with the Platform API. Create an organization-scoped key for each integration and restrict it to the access that integration needs. Browser clients can use their Console session on routes that accept session authentication.
Direct integrations authenticate with an API key. Send the key as the X-Api-Key header. DALP does not accept the key as a bearer token or a query parameter, so a client that copies a bearer-token pattern from another API fails authentication. Many Platform API routes also accept a valid Console session cookie (session-or-api-key): a browser client that already has a session does not need a long-lived key for those routes. Use a key when you are calling from a script, a backend, or any client that is not the signed-in Console.
curl "https://your-instance.example.com/api/v2/tokens" \
-H "X-Api-Key: sm_dalp_..."API keys identify a user and an organization. They do not satisfy gates that require a recent human login or two-factor authentication. Check the route reference when a task requires a signed-in Console session.
Create a key
Create a key for yourself, or for a named organization when your role permits it, with POST /api/auth/api-key/create. The /api/auth/* routes sit on the unversioned session and account surface, separate from the versioned /api/v2 Platform API that the key you create then authenticates against. The response is the only time the full secret value appears. Store it before you do anything else with the response; a later read of the same key returns metadata only, never the secret.
Create the key through the Console, or run dalp login for the browser device-code flow. CLI install and setup explains that flow, which creates a read-write key for the selected organization. A direct create call requires a signed-in session; consult the authentication API schema for its complete request and response.
DALP generates a 16-character key and prefixes it sm_dalp_. The first 8 characters of the prefix plus 6 more characters stay stored separately so a GET /api/auth/api-key/list or GET /api/auth/api-key/get call can show a truncated key for identification without exposing the secret.
A key you create has no expiration unless you set one: DALP enforces no default lifetime and no maximum, only that an expiration you request cannot be negative. A key with no expiration keeps working until you disable or delete it.
Scope: read or read-write
Every key carries a scope of read or read-write. A read key can call GET routes; it cannot call a route that creates, updates, or deletes a resource. Send read-write only to the keys that need it, and prefer separate keys per integration over one shared key with broad scope.
A read key that calls a mutating route receives DALP-0036 (SESSION_POLICY_DENIED), HTTP 403. This is not a transient failure: retrying with the same key returns the same result. Issue a read-write key for that integration instead. A key also remains bounded by its creator's organization permissions. Changing a key from read to read-write does not grant the creator a wider organization role. Use an account with the required permissions when creating a replacement for an integration that needs more access.
Organization scope
A key created for a named organization carries that organization's id in its metadata. DALP decodes the id at the authentication boundary and scopes every request the key makes to that organization; the caller does not repeat an organization id on each request. A key created without a named organization does not currently authenticate at all: session resolution requires an organization id in the key's metadata, and a key missing one is rejected rather than treated as its creator's own personal identity.
API keys and delegated authority
An API key identifies the caller. Delegated Authority lets an entitled caller act in another participant's context. An API-key request can send X-Participant when its underlying user holds the required authority. The key does not grant that authority by itself.
Manage keys
| Operation | Route | Notes |
|---|---|---|
| List | GET /api/auth/api-key/list | Returns metadata for your keys or a named organization's keys. Secret values are never included. |
| Read one | GET /api/auth/api-key/get | Returns metadata for the key named by id: expiry, remaining requests, enabled state. Not the secret. |
| Update | POST /api/auth/api-key/update | Changes metadata (including scope), expiry, or enabled state. Read the returned record to confirm the change. |
| Delete | POST /api/auth/api-key/delete | Deletes the key immediately. It cannot authenticate again. Issue a new key if the integration still needs access. |
Create, update, and delete need a signed-in session. List and read one also accept an API key.
Disabling a key is the reversible half of retiring one. The record survives and the secret stops working, and enabling it again restores the same key, so the integration resumes without a redeploy. Deleting is the permanent half, and the right tool once you know the secret has leaked. Disable a key while you are still working out whether an integration is at fault; delete it once you believe the secret is out.
Both take effect on the next request. DALP resolves an API-key request's identity from the key's own record every time it sees the header, rather than from a stored session that could outlive the key. A disabled or deleted key therefore fails with DALP-0002 from the first request after the change lands, and nothing else has to be restarted or invalidated for the cut-off to hold.
Read a key's own record before you conclude that an integration lost its secret. That record reports expiry, requests remaining in the current window, and whether the key is enabled, and the caller sees the same DALP-0002 for all three causes.
API keys on /api/auth routes
The /api/auth routes accept an API key on these eight read routes only:
GET /api/auth/get-sessionGET /api/auth/organization/listGET /api/auth/organization/get-full-organizationGET /api/auth/organization/list-membersPOST /api/auth/organization/has-permissionGET /api/auth/api-key/listGET /api/auth/api-key/getGET /api/auth/passkey/list-user-passkeys
A key on any other /api/auth route receives API_KEY_NOT_SUPPORTED_ON_ROUTE, HTTP 403, before the route runs. The refusal covers GET routes, routes that need no sign-in, POST /api/auth/sign-out, and any path the authentication API schema does not list. The same request with a signed-in Console session still works. A key therefore cannot create or update a key, approve a device sign-in, register a passkey, or sign in, so it cannot become a credential that outlives it. The authentication API schema lists API-key authentication only on the eight routes above.
The refusal does not limit a key on /api/v2. There a leaked key keeps working within its scope until it expires, or until you disable or delete it as Manage keys describes.
Rate limit
A rate limit is a property of the key rather than a platform constant. Each key carries three settings of its own: whether it is rate-limited at all, the length of the rolling window, and how many requests that window admits. On the platform's shipped defaults a key is limited, the window is 60 seconds, and the window admits 10,000 requests. The count is kept for that key alone rather than pooled across every key an organization has issued, so separate keys for separate integrations get separate budgets instead of sharing one ceiling. Any of the three can differ per key, including being switched off entirely, so read the key's own record rather than assuming the default. A request over that key's limit gets 429 Too Many Requests; back off until its window resets rather than retrying immediately.
Store the key correctly
Store the secret value in a secrets manager or environment variable, not in source control or a shared document. Rotate a key by creating a replacement, updating your integration to use it, then deleting the old key once the new one is confirmed working. DALP does not roll a key's secret value in place; delete and recreate instead.
Error codes
| Code | HTTP status | Retryable | When it happens |
|---|---|---|---|
DALP-0002 | 401 | No | The request has no X-Api-Key header, or the key is invalid, expired, or disabled. |
DALP-0036 | 403 | No | A read-scoped key called a mutating route, or a key called a route that does not accept API keys. |
API_KEY_NOT_SUPPORTED_ON_ROUTE | 403 | No | The key called an /api/auth route outside the eight read routes that accept a key. Call that route with a signed-in Console session. |
Full entries for the DALP- codes, including recovery copy, are on the DALP error index.
Next steps
- Pagination covers listing resources once you can authenticate.
- Errors covers the full error envelope and how to branch your integration on it.
- CLI install and setup covers
dalp login, which creates aread-writekey through a browser device-code flow instead of a direct API call.
Overview
Authenticate, generate a client, and integrate the DALP Platform API through guides, the CLI, the OpenAPI explorer, and the error catalog.
Pagination
Page DALP list endpoints with JSON:API sort, page, and filter query parameters, read the response links object, and stay inside the 200-item page-size cap.