Base URL
Authentication
All API requests require a Bearer token in the Authorization header:Content type
All requests and responses use JSON:Pagination
List endpoints support pagination with query parameters:
Paginated responses return:
Versioning
The API uses header-based versioning with semantic versions. Each platform environment is pinned to a specific API version on creation and will continue to receive that version’s response shapes, even as the API evolves.How it works
- Environment pin (default) - When you create an environment, it is pinned to the current API version. All requests from that environment automatically use that version.
- Per-request override - Send the
Keystone-Versionheader to override the pinned version for a single request. - Backward compatibility - The API always runs the latest logic internally. When your pinned version is older than the current version, responses are automatically transformed to match the schema you expect.
Keystone-Version response header confirms which version was used:
/v1/ URL prefix is a structural namespace, not the version itself. The actual version is controlled via the header and environment pin.
Admin endpoints (
/v1/admin/*) are never versioned - they always return the latest schema.Rate limits
The default rate limit is 600 requests per minute per environment. Rate-limited requests receive a429 response with a Retry-After header indicating when to retry.
A per-environment limit above the default is granted by KeyStone, not set through the API. Contact support to request one; the environments API reports the granted value as read-only
rate_limit_rpm, and a request that tries to write it is rejected with 422. Grants run up to 10,000 requests per minute. If your workload genuinely needs more than that, say so when you ask, because the ceiling itself has to move.
Requests without an environment
A request only counts against your environment’s limit when KeyStone can tell which environment it belongs to. That means a validAuthorization token, plus the X-Keystone-Environment header when you authenticate as a user rather than with client credentials.
A user-token request without X-Keystone-Environment (or naming an environment that does not exist) still counts against your platform: all such requests share one platform-wide window at the default limit, regardless of any raised per-environment limit. Send the header on every user-token request, including ones that would authenticate without it, so your traffic counts against the environment limit you were granted.
Anything KeyStone cannot attribute at all - an unauthenticated request, an expired or malformed token, an unknown identity - is counted against a separate, lower per-IP ceiling, defaulting to 120 requests per minute. A 429 from that ceiling carries "code": "RATE_LIMIT_UNATTRIBUTED" instead of "code": "RATE_LIMIT_EXCEEDED", so you can always tell the shared ceiling from your own contractual limit. A retry loop against an endpoint that keeps returning 401 consumes that ceiling; fix the credentials rather than retrying harder.
Attribution requires a token KeyStone has authenticated, so a newly issued token’s first request or two may report the shared ceiling in their X-RateLimit-* headers before the token is recognised. Everything after that counts against your own limit. Reuse a token for its full lifetime rather than fetching a new one per request.
All limits report the same X-RateLimit-* headers, which describe the window the request was counted on.