Managing API Access
Authentication covers minting a token, business scoping, scopes, IP allowlists, rate limits and the client-credentials request itself. This guide covers everything around the credential's life: asking for API access, listing and revoking tokens, registering and operating partner API clients, disconnecting connected apps (MCP OAuth grants), and what each revocation does to live sessions. The Settings screen for all of this is described in the Developers article of the help center; the routes below are what that screen calls.
All paths are relative to https://api.ondayzero.com. None of these routes take x-business-id: credentials belong to a person, not a business. Successful responses use the usual {"success": true, "data": ...} envelope (examples below show data) and errors follow Error Handling.
What exists, so you do not go looking for the rest:
| Area | Routes | Notes |
|---|---|---|
| API access | GET /api/v1/tokens/access, POST /api/v1/tokens/access-request |
Ask DayZero for access, check the answer |
| API tokens | GET /api/v1/tokens, POST /api/v1/tokens/{token_id}/revoke, DELETE /api/v1/tokens/{token_id}, POST /api/v1/tokens/{token_id}/rotate, GET /api/v1/tokens/client-ip |
Create is in Authentication. There is no GET /tokens/{id}; read a token's record from the list |
| API clients | /api/v1/api-clients and its sub-routes |
There is no delete; a client is disabled (and can be re-enabled) |
| Connected apps | GET /api/v1/oauth/grants, DELETE /api/v1/oauth/grants/{grant_id}, POST /api/v1/oauth/grants/{grant_id}/revoke |
MCP clients such as Claude or Cursor |
| OAuth token services | POST /api/v1/oauth2/partner/token, /token, /exchange, /refresh |
See OAuth token endpoints |
There is no public audit endpoint for credentials. API client changes are written to the audit trail (visible in the app's Audit Log), but the audit routes are internal and not part of the public API. For an activity signal on a token, read last_used_at from the list; unusual use (bursts over budget, blocked IPs, use after revocation, a first sighting from a new source network, meaning a new /24 for IPv4 or /48 for IPv6) also alerts the token's owner.
Who may manage whose credentials
Only the owner. Every token, API client and connected-app route is scoped to the signed-in user. Another user's token id, client id or grant id answers 404, exactly like an id that does not exist. A firm owner or admin cannot list, rotate or revoke a staff member's tokens through the API.
What a firm owner or admin can do is switch API access off for a staff member (PATCH /api/v1/advisory-firms/{firm_id}/users/{user_id}/api-access, see API access per person). The switch can only restrict: approval always comes from DayZero.
| Route | API token may call it | Needs a signed-in web session | Two-factor step-up | Needs approved API access |
|---|---|---|---|---|
GET /tokens/access, POST /tokens/access-request, GET /tokens/client-ip |
Yes | No | No | No |
GET /tokens |
Yes | No | No | Yes |
POST /tokens/{id}/revoke, DELETE /tokens/{id} |
Yes | No | No | No |
POST /tokens, POST /tokens/{id}/rotate |
No (403 AUTH_057) |
Yes | Yes | Yes |
GET/POST /api-clients, GET/PATCH /api-clients/{id} |
No (403 AUTH_057) |
Yes | Create, and PATCH of anything but name/description |
Yes |
PUT /api-clients/{id}/jwks, POST .../signing-keys, POST .../enable |
No | Yes | Yes | Yes |
POST .../signing-keys/{kid}/retire, POST .../disable |
No | Yes | No | Yes |
/oauth/grants routes |
Yes | No | No | No |
Notes on the table:
- "Two-factor step-up" is the same check as minting a token: the account needs a second factor enrolled and the session must have verified both factors recently (
403AUTH_050if the session has none,AUTH_056if the check is stale). Revoking never asks for it, so an incident responder can cut access off in one call. - An API token still obeys its own scope. A
read_onlytoken can list but cannot revoke or delete (403AUTH_048), and acredit*token is limited to the credit API, so it cannot reach any route in this guide. A leaked full-access key can therefore revoke tokens but never mint, rotate or widen them. - MCP OAuth tokens never work on these routes (or anywhere else on the REST API).
- Listing tokens needs approved API access; revoking and deleting do not, so you can always clean up after access is taken away.
Request API access
API access is off for every account until a DayZero operator approves a request.
curl -X POST "https://api.ondayzero.com/api/v1/tokens/access-request" \
-H "Authorization: Bearer SESSION_OR_API_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"use_case_kind": "reporting_sync",
"use_case": "Nightly sync of paid invoices into our data warehouse, read-only, from one server.",
"company_name": "Northwind Advisory"
}'| Field | Notes |
|---|---|
use_case_kind |
One of internal_automation, reporting_sync, firm_client_workflows, product_integration, ai_agent, migration, evaluating, other |
use_case |
Your own words, up to 2000 characters. Optional with a listed kind other than other; otherwise at least 20 characters (400 if too short) |
company_name |
Optional, up to 255 characters |
Send either a kind or a use_case of 20+ characters. The response is the access state (below) with status pending. DayZero emails the reviewers, and emails you when the request is approved or denied.
Constraints: one open request at a time (409 CONFLICT_095), nothing to request once approved (409 CONFLICT_096), and three requests per account per day (429). A denied or revoked account may ask again.
curl "https://api.ondayzero.com/api/v1/tokens/access" \
-H "Authorization: Bearer SESSION_OR_API_TOKEN"{
"status": "pending",
"can_request": false,
"request": {
"id": "01912345-abcd-7000-8000-0000000000a1",
"status": "pending",
"use_case_kind": "reporting_sync",
"use_case_kind_label": "Syncing data to a warehouse or BI tool",
"use_case": "Nightly sync of paid invoices into our data warehouse, read-only, from one server.",
"company_name": "Northwind Advisory",
"requested_at": "2026-10-11T14:02:11Z",
"decided_at": null,
"decision_note": null
}
}status |
Meaning |
|---|---|
not_requested |
Never asked; request is null |
pending |
Waiting for DayZero |
approved |
You may create and use tokens |
denied |
Turned down; decision_note may say why. can_request is true |
revoked |
Taken away after approval. can_request is true |
firm_disabled |
Approved, but your firm switched API access off for you |
can_request is true only for not_requested, denied and revoked.
What removing access does. The check runs on every API-token request, not only when you manage tokens. When your firm switches access off, every token you hold is refused with 403 AUTH_047 immediately; the tokens stay in your list and work again if the switch is turned back on. When DayZero revokes an approval, all your active tokens are revoked (reason "API access revoked by DayZero") and stay revoked if access is approved again, so you mint new ones. Until access is approved, creating, rotating and listing tokens answer 403 AUTH_069.
API tokens
GET /api/v1/tokens/client-ip returns {"ip": "203.0.113.10"}, the address your request arrives from, handy for filling in allowed_ips when minting.
List tokens
curl "https://api.ondayzero.com/api/v1/tokens?limit=20&include_revoked=true" \
-H "Authorization: Bearer dz_your_token_here"The list is cursor-paginated. By default it omits revoked tokens; include_revoked=true adds them. Tokens that a partner API client obtained through the client-credentials grant are never listed here (they are minted by the hundred and live minutes); see API clients.
{
"items": [
{
"id": "01912345-abcd-7000-8000-0000000000b2",
"jti": "Zk3p9Qm1xV7c0TnB5uYw2hLd",
"name": "Month-end close agent",
"description": "Read-only token for the reporting assistant",
"token_prefix": "dz_Zk3p9Qm1",
"token_type": "api",
"scopes": "read_only",
"allowed_ips": ["203.0.113.10"],
"rate_limit_per_minute": 600,
"business_ids": ["01912345-abcd-7000-8000-000000000001"],
"status": "active",
"rotated_from_id": null,
"rotated_to_id": null,
"grace_until": null,
"created_at": "2026-10-01T09:30:00",
"last_used_at": "2026-10-11T13:58:02",
"expires_at": "2026-12-30T09:30:00",
"revoked_at": null,
"revocation_reason": null
}
],
"next_cursor": null,
"prev_cursor": null,
"has_next": false,
"has_prev": false,
"limit": 20,
"total": null
}id is what the revoke, delete and rotate routes take (not jti). scopes is a space-separated string; a token with no explicit scope shows api. allowed_ips, business_ids and rate_limit_per_minute are null when unrestricted or on the platform default. The plaintext token is never returned. status is active, rotating, revoked or expired.
Revoke a token
curl -X POST "https://api.ondayzero.com/api/v1/tokens/01912345-abcd-7000-8000-0000000000b2/revoke" \
-H "Authorization: Bearer dz_your_admin_token_here" \
-H "Content-Type: application/json" \
-d '{"reason": "Laptop lost"}'The body and reason (free text) are optional. The record is kept and marked revoked.
{
"id": "01912345-abcd-7000-8000-0000000000b2",
"jti": "Zk3p9Qm1xV7c0TnB5uYw2hLd",
"name": "Month-end close agent",
"revoked_at": "2026-10-11T14:10:44",
"revoked_by": "5f0c2b1e-0000-4000-8000-000000000000",
"revocation_reason": "Laptop lost"
}revoked_by is the revoking user's id (the schema describes it as an email, but the service stores the id; treat it as an opaque value). Revoking is permanent: there is no un-revoke. Revoking a token that is already revoked is 400 VALIDATION_107. An unknown id, or one that belongs to someone else, is 404 NOT_FOUND_049.
You can revoke the token you are calling with; the response is returned, and the next request with it fails.
Delete a token
DELETE /api/v1/tokens/{token_id} blacklists the token and then removes its record. It returns the standard message envelope. Prefer revoke: a deleted token leaves no row to show when it was last used or why it was withdrawn.
Rotate a token
Rotation mints a replacement that inherits the name, description, scopes, IP allowlist, rate limit and business limit, and keeps the old token working for an overlap window. It is a web-app call (session plus two-factor step-up); an API token gets 403 AUTH_057. The request body is optional:
{ "overlap_hours": 24, "expires_in_days": 90 }overlap_hours is 0 to 168 (default 24; 0 revokes the old token at once). expires_in_days is 1 to 365 and defaults to the old token's original lifetime. The response:
{
"token": "dz_the_new_token_shown_once",
"token_info": { "id": "01912345-abcd-7000-8000-0000000000c3", "status": "active", "rotated_from_id": "01912345-abcd-7000-8000-0000000000b2" },
"replaced_token": { "id": "01912345-abcd-7000-8000-0000000000b2", "status": "rotating", "grace_until": "2026-10-12T14:15:00", "rotated_to_id": "01912345-abcd-7000-8000-0000000000c3" }
}(token_info and replaced_token carry the full record shown in the list.) Rotation rules:
- Until
grace_untilboth tokens work. After it the old token is refused with401AUTH_059, and use of a rotated-out token is reported to the owner as unusual activity. - A token can be rotated once (
400VALIDATION_473); rotate the replacement next time. A revoked or expired token cannot be rotated (400VALIDATION_474). - Rotation counts against the same budget as minting: 10 creates or rotations per user per hour (
429), but a token that has been rotated (still inside its overlap window) does not count toward the 10-active-token limit, so rotating at the limit works. - You can revoke the old token early, before
grace_until, once your integration has switched over.
API clients
An API client is the hardened alternative to a long-lived token, for a partner's servers. You register the public half of a signing key; the partner signs a short-lived assertion and exchanges it at POST /api/v1/oauth2/partner/token for an access token that lives 1 to 60 minutes. No long-lived secret leaves the partner. The request format for that exchange is in Authentication; the assertion's claims are below.
Clients are provisioned for approved partners and are managed by the owner, the DayZero user the client acts as. Tokens a client obtains act as that user, with the client's scopes, IPs, rate limit and (when the token request asks) business limit. All routes need a signed-in web session with approved API access. Each user may own up to 10 active clients (400 VALIDATION_481).
Create a client
POST /api/v1/api-clients (two-factor step-up; 10 creations per user per hour).
{
"name": "Tie production",
"description": "Tie's payment job",
"scopes": ["credit:payments"],
"allowed_ips": ["203.0.113.10"],
"rate_limit_per_minute": 600,
"token_ttl_seconds": 900,
"jwks": {
"keys": [
{ "kty": "EC", "crv": "P-256", "kid": "tie-2026-10", "use": "sig", "alg": "ES256", "x": "f83OJ3D2xF1Bg8vub9tLe1gHMzV76e8Tus9uPHvRVEU", "y": "x_FEzRu9m36HLN_tue659LNpXW6pCyStikYjKIWI5a0" }
]
},
"require_mtls": false,
"require_signed_requests": true
}| Field | Notes |
|---|---|
name |
Required, 1 to 255 characters |
description |
Optional, up to 2000 characters |
scopes |
At least one of api (full access), read_only, credit, credit:read, credit:payments; default ["credit:read"]. Same rules as tokens: a credit scope cannot be combined with api or read_only |
allowed_ips |
Up to 32 IPv4/IPv6 addresses or CIDR ranges. Applies to token requests and to using the issued tokens. Unlike tokens, cloud presets are not accepted. Omit for any IP |
rate_limit_per_minute |
10 to 6,000 per issued token; omit for the default |
token_ttl_seconds |
Lifetime of each issued token, 60 to 3600; default 900 |
jwks |
Required. A JWK set of public keys: RS256 (RSA, 2048 bits or more), ES256 (P-256) or EdDSA (Ed25519). Up to 10 keys; with more than one key every key needs a unique kid. Private members are refused (400 VALIDATION_475) |
require_mtls |
Bind each token to the client certificate presented at the token endpoint. Refused (400 AUTH_075) where the load balancer does not forward certificates; check mtls_available in the list response |
mtls_cert_thumbprints |
Optional pin list of up to 20 SHA-256 certificate thumbprints (hex or base64url) |
require_signed_requests |
Payment writes must carry a request signature; see Signed payment requests |
The response is the client record. Put its client_id (dzc_...) in both iss and sub of every assertion:
{
"id": "01912345-abcd-7000-8000-0000000000d4",
"client_id": "dzc_3f9a1c07b2e84d5a6c1e90ab",
"name": "Tie production",
"status": "active",
"scopes": ["credit:payments"],
"allowed_ips": ["203.0.113.10"],
"rate_limit_per_minute": 600,
"token_ttl_seconds": 900,
"jwks": { "keys": ["..."] },
"key_ids": ["tie-2026-10"],
"require_mtls": false,
"mtls_cert_thumbprints": null,
"require_signed_requests": true,
"signing_keys": [],
"active_token_count": 0,
"last_token_issued_at": null,
"disabled_at": null,
"created_at": "2026-10-11T14:20:00Z",
"updated_at": null,
"mtls_available": false
}There is no client secret to rotate or lose: authentication is the assertion signature. Secrets only exist for signing keys (below), and they are shown once.
List, get and update
GET /api/v1/api-clientsreturns{"items": [...], "mtls_available", "token_endpoint", "assertion_audiences", "max_clients"}. It is not paginated and returns no secrets.token_endpointandassertion_audiencesare exactly what the partner needs to build assertions.GET /api/v1/api-clients/{client_pk}returns one client (404NOT_FOUND_109for an unknown or foreign id).client_pkis theid, not theclient_id.PATCH /api/v1/api-clients/{client_pk}changes only the fields you send:name,description,scopes,allowed_ips,rate_limit_per_minute,token_ttl_seconds,require_mtls,mtls_cert_thumbprints,require_signed_requests. Sendallowed_ips: []to allow any IP. A rename or description change needs only a session; changing anything else needs the two-factor step-up. Changes apply to tokens issued from then on; tokens already issued keep their claims until they expire (at mosttoken_ttl_seconds).
Rotate the signing key
PUT /api/v1/api-clients/{client_pk}/jwks with {"jwks": {...}} replaces the whole key set (step-up). To rotate with no gap: upload old and new keys together, switch the partner's signer to the new key, then upload the new key alone. Tokens already issued stay valid until they expire.
Request-signing keys
Clients that sign payment writes register a signing key per environment (up to 5 live at once; 400 VALIDATION_477 beyond that or for a duplicate kid).
POST /api/v1/api-clients/{client_pk}/signing-keys (step-up):
| Field | Notes |
|---|---|
alg |
hmac-sha256 or ed25519 |
kid |
Optional, A-Za-z0-9._-, 1 to 64 characters; generated (sk_...) when omitted |
public_key |
Ed25519 only: the raw 32-byte public key, base64 or base64url. Sending it with hmac-sha256 is a 400 |
For hmac-sha256 DayZero generates the shared secret and returns it once in secret; it is stored encrypted and never shown again. The response is {"client": {...}, "signing_key": {"kid", "alg", "public_key", "created_at", "retired_at", "status"}, "secret": "..."} with secret null for Ed25519. A key's status is active, retiring (retirement scheduled) or retired.
POST /api/v1/api-clients/{client_pk}/signing-keys/{kid}/retire takes an optional {"overlap_hours": 0-168} (default 0, retire now) so the partner can roll out a replacement first. A retirement can be brought forward but never pushed back. Unknown kid is 404 NOT_FOUND_111. No step-up is needed. Which headers carry the signature is described in the credit guide linked above.
Disable and re-enable (revoke a client)
POST /api/v1/api-clients/{client_pk}/disable (no step-up) stops the client and revokes every live access token issued to it, effective on the next request:
{ "client": { "id": "01912345-abcd-7000-8000-0000000000d4", "status": "disabled", "disabled_at": "2026-10-11T15:00:00Z" }, "revoked_token_count": 3 }The partner's token requests then fail with 401 invalid_client and AUTH_067. Disabling is repeatable.
POST /api/v1/api-clients/{client_pk}/enable (step-up) re-activates it. Tokens revoked at disable time stay revoked; the partner simply requests new ones. Enabling re-checks the 10-active-clients limit and, for require_mtls, that mTLS is still available.
Partner token requests: assertion rules
Authentication gives the form fields of POST /api/v1/oauth2/partner/token. The assertion is a JWT you sign with a key in the client's JWK set:
| Claim | Requirement |
|---|---|
header alg |
RS256, ES256 or EdDSA, and it must match the registered key's type. none and HMAC are refused |
header kid |
Required when the client has more than one key |
iss, sub |
Both equal the client's client_id |
aud |
A value from assertion_audiences in the client list (the token endpoint URL is the standard choice) |
iat, exp |
Required; exp minus iat at most 300 seconds; 30 seconds of clock skew is tolerated |
jti |
Required and never reused: a repeat is refused (401 AUTH_076). Use a fresh random value per request |
The optional scope can only narrow the client's scopes (credit covers credit:read and credit:payments; api covers read_only); anything else is 400 invalid_scope. business_id accepts one or more space- or comma-separated UUIDs of businesses the owner can reach and limits the token to them. The token expires after the client's token_ttl_seconds and carries the client's IP allowlist, rate limit and (with mTLS) its certificate binding.
error |
Status | Typical cause |
|---|---|---|
invalid_client |
401 |
Bad or replayed assertion, unknown or disabled client (AUTH_067), IP not allowed (AUTH_028), missing or wrong certificate |
invalid_grant |
400 |
The owner is inactive (AUTH_078) or lost API access (AUTH_069, AUTH_047) |
invalid_scope |
400 |
scope outside what the client holds |
unsupported_grant_type |
400 |
grant_type is not client_credentials (AUTH_077) |
invalid_request |
400 |
A business_id that is not a UUID or not reachable |
rate_limited |
429 |
60 requests per minute per source IP, or 30 issued tokens per minute per client; wait for Retry-After |
If Redis-backed replay protection is briefly unavailable the endpoint answers 503 rather than issue a token it cannot protect; retry shortly. Responses are never cached.
Connected apps (OAuth grants)
When you approve an MCP client such as Claude, ChatGPT or Cursor, DayZero records a grant (see MCP Server for the sign-in flow). Grants are about MCP access only; they do not touch REST API tokens.
curl "https://api.ondayzero.com/api/v1/oauth/grants" \
-H "Authorization: Bearer dz_your_token_here"{
"items": [
{
"id": "01912345-abcd-7000-8000-0000000000e5",
"client_id": "mcp_client_abc",
"client_name": "Claude",
"scopes": ["mcp:read", "mcp:write", "offline_access"],
"granted_at": "2026-09-20T10:00:00",
"last_used_at": "2026-10-11T12:30:00",
"business_id": null,
"business_name": null
}
]
}Only active grants are listed, in a single unpaginated array. business_id and business_name are set when the person limited that connection to one business on the consent screen (every token of the grant then reaches only that business) and null when it reaches every business they can. One app can hold several business-bound connections next to one unbound one, and each is its own grant. To disconnect one:
curl -X DELETE "https://api.ondayzero.com/api/v1/oauth/grants/01912345-abcd-7000-8000-0000000000e5" \
-H "Authorization: Bearer dz_your_token_here"POST /api/v1/oauth/grants/{grant_id}/revoke is an alias that also accepts an optional {"reason": "..."}. The response is {"id", "client_id", "client_name", "revoked_at"}. grant_id must be a UUID (400 otherwise); an unknown or foreign grant is 404 NOT_FOUND_094; revoking twice is 400 VALIDATION_107.
Revoking blacklists the grant's refresh token and every active MCP access and refresh token issued under it, including ones from earlier refreshes, so the app loses access on its next call rather than when its access token would have expired. Revoking one business-bound connection leaves the person's other connections for the same app alone. The app can connect again by going through the consent screen, which reactivates the same grant record.
What revoking does
| Action | Effect on live use | Effect on everything else |
|---|---|---|
| Revoke or delete an API token | That token is refused on its next request (401) |
Other tokens, your web session, MCP grants and API clients are untouched |
| Rotate with an overlap | Both tokens work until grace_until, then the old one gets 401 AUTH_059 |
Replacement inherits all limits |
Rotate with overlap_hours 0 |
Old token refused at once | |
| Disable an API client | All its live access tokens are revoked at once; new token requests fail | Re-enabling does not restore them. The owner's own tokens are untouched |
| Revoke a connected app | Its MCP access and refresh tokens are blacklisted at once | REST API tokens are untouched; the user's session is untouched |
| Firm switches API access off | All of the person's tokens and clients are refused (AUTH_047) |
Nothing is revoked; turning it back on restores them |
| DayZero revokes API access | All the person's active tokens are revoked | Approval later does not revive them |
| Owner's second factor removed | Their tokens are revoked and their API clients disabled, and they are emailed | Turning two-factor back on does not revive them; mint new ones |
OAuth token endpoints
Beyond the partner endpoint, /api/v1/oauth2 serves three more routes. They are provisioned for DayZero's own apps and partner backends; for your own integrations use an API token.
POST /api/v1/oauth2/token(form-encoded) issues an access and refresh token for the user named byuser_email, authenticated by a shared-secret signature: sendclient_id,timestamp(Unix seconds, within 5 minutes of now), a single-usenonce, andsignature, the hex HMAC-SHA256 ofclient_id|timestamp|nonce|user_email. It answers404unless enabled for the deployment, may be limited to an IP allowlist (403AUTH_028), is limited to 30 requests per minute per IP, and never issues tokens for DayZero staff (403AUTH_093) or inactive accounts. Signature problems are401(AUTH_030bad signature,AUTH_031nonce reused,AUTH_032stale timestamp).POST /api/v1/oauth2/refresh(form-encodedrefresh_token, andclient_idwhen the token is bound to one) returns a new access token and rotates the refresh token: use the new one next time. Replaying an already-rotated refresh token after a short grace window (about 5 minutes) is treated as theft and revokes the whole token family. 60 requests per minute per IP.POST /api/v1/oauth2/exchangeis called by the DayZero web app. It trades a single-use authorization code (10-minute lifetime) from the sign-in redirect, or a refresh token, for tokens. It needs no client credentials and is limited to 30 requests per minute per IP. Integrations should not use it.
All three return {"access_token", "token_type": "Bearer", "expires_in", "refresh_token", "scope"} outside the usual envelope. The MCP authorization server (/oauth2/register, /oauth2/authorize, /oauth2/mcp/token and the .well-known metadata) is served separately and documented in the MCP Server guide.
Errors at a glance
| Status | code |
Meaning |
|---|---|---|
400 |
VALIDATION_107 |
Token or grant already revoked |
400 |
VALIDATION_166 |
10 active tokens already |
400 |
VALIDATION_473 / VALIDATION_474 |
Token already rotated / cannot be rotated (revoked or expired) |
400 |
VALIDATION_475 / 477 / 481 |
Invalid JWK set / invalid signing key / 10 active clients |
400 |
AUTH_075 |
require_mtls is not available in this environment |
403 |
AUTH_050 / AUTH_056 / AUTH_057 |
No second factor on the session / stale check / an API token cannot do this |
403 |
AUTH_069 / AUTH_047 |
API access not approved / switched off by your firm |
403 |
AUTH_048 |
The calling token's scope does not allow it |
404 |
NOT_FOUND_049 / NOT_FOUND_109 / NOT_FOUND_111 / NOT_FOUND_094 |
Token / API client / signing key / grant not found (or not yours) |
409 |
CONFLICT_095 / CONFLICT_096 |
Access request already open / access already approved |
429 |
GEN_005 |
Creation, rotation or access-request limit hit; wait and retry |
Not covered
Operator-side approval of access requests and admin token management are internal and not part of the public API. Webhook endpoints for partner credit are covered in the Credit and Webhooks guides, and the interactive MCP consent flow in MCP Server.