API · 2.0.0

Keys

Manage API keys. Like everything in this document these endpoints take your session; the keys they mint authenticate the v1 API (`/api/v1`) and the MCP server, not these endpoints.

5 operations, each listing how it authenticates. This is the session-authenticated API the web app uses; if you have an API key, use the v1 API instead (see the overview). Responses use the standard envelope; the overview also covers shapes and error codes.

get/keys

List the calling user's API keys

Scoped to the session user, not the org — a teammate's keys are never listed here. For the org-wide v1 key inventory see `GET /org/{orgId}/api-keys`.

Auth: your signed-in session (cookie __Secure-next-auth.session-token). API keys are not accepted.

Responses

  • 200 - Keys (no secrets).
  • 400 - Validation failed. `error.code = VALIDATION_ERROR`. `error.details.errors` lists per-field issues from zod.
  • 401 - No valid credentials for this operation's `security` requirement. `error.code = AUTH_ERROR`.
  • 403 - Authenticated but not allowed (wrong role, not a member, or org scope mismatch). `error.code = FORBIDDEN`.
  • 404 - Resource does not exist or is invisible to the caller. `error.code = NOT_FOUND`.
  • 409 - Conflict — duplicate slug, race condition, or invalid state transition. `error.code = CONFLICT`.
  • 429 - Rate limit exceeded. `error.code = RATE_LIMIT`. Retry after the window listed in `Retry-After`.
  • 500 - Unexpected server error. `error.code = INTERNAL_ERROR`. Logged with the `requestId` echoed in metadata.
cURL example
curl -X GET https://switchy.build/api/keys \
  -H 'Cookie: __Secure-next-auth.session-token=<session cookie>'
post/keys

Mint an API key

Returns the raw key once. After this response it can only be rotated, not retrieved.

Auth: your signed-in session (cookie __Secure-next-auth.session-token). API keys are not accepted.

Request body

FieldTypeRequiredDescription
namestringyes
scopesstring[]yes

Responses

  • 201 - Created. `secret` shown once.
  • 400 - Validation failed. `error.code = VALIDATION_ERROR`. `error.details.errors` lists per-field issues from zod.
  • 401 - No valid credentials for this operation's `security` requirement. `error.code = AUTH_ERROR`.
  • 403 - Authenticated but not allowed (wrong role, not a member, or org scope mismatch). `error.code = FORBIDDEN`.
  • 404 - Resource does not exist or is invisible to the caller. `error.code = NOT_FOUND`.
  • 409 - Conflict — duplicate slug, race condition, or invalid state transition. `error.code = CONFLICT`.
  • 429 - Rate limit exceeded. `error.code = RATE_LIMIT`. Retry after the window listed in `Retry-After`.
  • 500 - Unexpected server error. `error.code = INTERNAL_ERROR`. Logged with the `requestId` echoed in metadata.
cURL example
curl -X POST https://switchy.build/api/keys \
  -H 'Cookie: __Secure-next-auth.session-token=<session cookie>' \
  -H 'Content-Type: application/json' \
  -d '{ ... }'
get/org/{orgId}/api-keys

List the org's v1 API keys

Metadata only — id, name, prefix, scopes, timestamps. Nothing returned here can reconstruct a key. Requires OWNER or ADMIN.

Auth: your signed-in session (cookie __Secure-next-auth.session-token). API keys are not accepted.

Parameters

NameInRequiredTypeDescription
orgIdpathyesstringCUID

Responses

  • 200 - Keys (no secrets).
  • 400 - Validation failed. `error.code = VALIDATION_ERROR`. `error.details.errors` lists per-field issues from zod.
  • 401 - No valid credentials for this operation's `security` requirement. `error.code = AUTH_ERROR`.
  • 403 - Authenticated but not allowed (wrong role, not a member, or org scope mismatch). `error.code = FORBIDDEN`.
  • 404 - Resource does not exist or is invisible to the caller. `error.code = NOT_FOUND`.
  • 409 - Conflict — duplicate slug, race condition, or invalid state transition. `error.code = CONFLICT`.
  • 429 - Rate limit exceeded. `error.code = RATE_LIMIT`. Retry after the window listed in `Retry-After`.
  • 500 - Unexpected server error. `error.code = INTERNAL_ERROR`. Logged with the `requestId` echoed in metadata.
cURL example
curl -X GET https://switchy.build/api/org/:orgId/api-keys \
  -H 'Cookie: __Secure-next-auth.session-token=<session cookie>'
post/org/{orgId}/api-keys

Mint an org-wide v1 API key

Returns the plaintext `sk_live_...` key exactly once, in this response. It is stored only as a hash and can never be retrieved again — only revoked. The key acts as the org, not as its creator: it reads and writes the org's ORG memories through the namespace endpoints and /api/v1/memory and /memory/search, and every other /api/v1 endpoint refuses it. Minting requires OWNER or ADMIN; a MEMBER gets 403.

Auth: your signed-in session (cookie __Secure-next-auth.session-token). API keys are not accepted.

Parameters

NameInRequiredTypeDescription
orgIdpathyesstringCUID

Request body

FieldTypeRequiredDescription
namestringyesHuman label shown in the key list.
scopes"memory:read" | "memory:write"[]noDefaults to `["memory:read","memory:write"]`.

Responses

  • 201 - Created. `key` is shown once and never again.
  • 400 - Validation failed. `error.code = VALIDATION_ERROR`. `error.details.errors` lists per-field issues from zod.
  • 401 - No valid credentials for this operation's `security` requirement. `error.code = AUTH_ERROR`.
  • 403 - Authenticated but not allowed (wrong role, not a member, or org scope mismatch). `error.code = FORBIDDEN`.
  • 404 - Resource does not exist or is invisible to the caller. `error.code = NOT_FOUND`.
  • 409 - Conflict — duplicate slug, race condition, or invalid state transition. `error.code = CONFLICT`.
  • 429 - Rate limit exceeded. `error.code = RATE_LIMIT`. Retry after the window listed in `Retry-After`.
  • 500 - Unexpected server error. `error.code = INTERNAL_ERROR`. Logged with the `requestId` echoed in metadata.
cURL example
curl -X POST https://switchy.build/api/org/:orgId/api-keys \
  -H 'Cookie: __Secure-next-auth.session-token=<session cookie>' \
  -H 'Content-Type: application/json' \
  -d '{ ... }'
delete/org/{orgId}/api-keys/{keyId}

Revoke an org API key

Idempotent — revoking an already-revoked key returns 200 with the original `revokedAt`. Keys belonging to another org return 404. Requires OWNER or ADMIN.

Auth: your signed-in session (cookie __Secure-next-auth.session-token). API keys are not accepted.

Parameters

NameInRequiredTypeDescription
orgIdpathyesstringCUID
keyIdpathyesstringCUID

Responses

  • 200 - Revoked.
  • 400 - Validation failed. `error.code = VALIDATION_ERROR`. `error.details.errors` lists per-field issues from zod.
  • 401 - No valid credentials for this operation's `security` requirement. `error.code = AUTH_ERROR`.
  • 403 - Authenticated but not allowed (wrong role, not a member, or org scope mismatch). `error.code = FORBIDDEN`.
  • 404 - Resource does not exist or is invisible to the caller. `error.code = NOT_FOUND`.
  • 409 - Conflict — duplicate slug, race condition, or invalid state transition. `error.code = CONFLICT`.
  • 429 - Rate limit exceeded. `error.code = RATE_LIMIT`. Retry after the window listed in `Retry-After`.
  • 500 - Unexpected server error. `error.code = INTERNAL_ERROR`. Logged with the `requestId` echoed in metadata.
cURL example
curl -X DELETE https://switchy.build/api/org/:orgId/api-keys/:keyId \
  -H 'Cookie: __Secure-next-auth.session-token=<session cookie>'