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:

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:

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

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.