Authentication
Every operation except GET /api/v1/health and the OpenAPI document requires an organization-scoped API key.
Obtaining a key
Two paths, and they produce the same kind of key:
- Workspace settings — mint one in the dashboard when a human is setting up an integration.
POST /api/v1/api-keys— exchange email, password, and an organization id for a key when a script needs to bootstrap itself. See the quickstart for the request.
Credential exchange is as powerful as a login, so it is rate limited to 5 requests per minute keyed on the calling IP and the email, and it fails closed when limits cannot be enforced. It verifies your credentials without creating a session — it does not log you in.
Sending a key
Either header works. Authorization: Bearer is the primary convention; x-api-key is accepted for clients that reserve the Authorization header:
curl https://app.khotan.com/api/v1/me \
-H "Authorization: Bearer $KHOTAN_API_KEY"
curl https://app.khotan.com/api/v1/me \
-H "x-api-key: $KHOTAN_API_KEY"
Session cookies are not accepted on /api/v1. An unauthenticated request returns a JSON 401, never a redirect to a sign-in page, so a script never has to distinguish an auth failure from an HTML response.
What a key carries
A key is bound to one organization and one role. That has three consequences worth internalising:
- No request names an organization. There is no account, workspace, or tenant parameter anywhere in the API, and no request can widen its own scope.
- The host is irrelevant. Since the key resolves the organization,
https://app.khotan.comserves every workspace. - A key cannot exceed its minter. You cannot mint a key carrying more access than your own role in that organization.
Confirm the binding before trusting any automated run:
curl -s https://app.khotan.com/api/v1/me \
-H "Authorization: Bearer $KHOTAN_API_KEY"
{ "organizationId": "org_...", "role": "member", "keyId": "..." }
Roles
A key carries the role it was minted with. Most resource operations need only a valid key scoped to the organization — the role is not checked. Key management is the exception: listing an organization's keys, or acting on a key other than your own, requires a role holding the manageApiKeys permission.
Keeping a key safe
- Never commit one. Keys belong in environment variables or a secret manager, not in a repository, a container image, or a CI log.
- Never ship one to a browser. The API sends no cross-origin headers precisely because an organization-scoped key must not reach client-side code. See conventions.
- Mint one per integration. Separate keys make it possible to revoke one consumer without disrupting the rest, and make audit logs attributable.
- Treat the response as the only copy. The plaintext key is returned exactly once and is never retrievable afterwards. Losing it means minting a replacement.
Managing keys
Existing keys are listed and revoked from workspace settings in the dashboard. Revocation takes effect immediately: the next request carrying that key is rejected 401.