← Documentation

Errors

Every error code the API returns, what causes it, and whether to retry.

Every failure returns a JSON body with a stable machine-readable error code. Branch on error, never on message — messages are written for humans and are reworded without notice.

Response shape

{
  "error": "KYC_REQUIRED",
  "message": "Person must have approved KYC",
  "details": { "personDid": "did:bfid:person:..." }
}

details is present only on codes that carry structured context.

Request-body validation failures carry the field-level problems instead:

{
  "error": "VALIDATION_ERROR",
  "message": "...",
  "issues": [{ "path": ["ownerPublicKey"], "message": "Required", "code": "invalid_type" }]
}

issues lists field-level problems — path locates the offending field, which is usually enough to fix the call without a support ticket.

Unhandled server faults return INTERNAL with a fixed "Internal error" message. Quote your x-correlation-id (see Authentication) when opening a support ticket.

Codes

Authentication and authorization

CodeHTTPMeaningWhat to do
UNAUTHORIZED401Missing, malformed, revoked, or expired key; or a bad request signatureCheck the bearer header. If signing is on, see the signing failure table — the message distinguishes skew, replay, and mismatch
FORBIDDEN403Key is valid but lacks the scope, or the caller's IP is outside the allowlistMint a key with the right scope, or add the egress address you get from GET /v1/whoami
RATE_LIMITED429Plan quota or the per-IP backstop exceededWait x-ratelimit-plan-reset seconds, then retry with jitter

Request problems

CodeHTTPMeaningWhat to do
VALIDATION_ERROR400Body or query failed schema validationRead issues[].path; fix the field
BAD_REQUEST400Well-formed but not acceptable — e.g. an Idempotency-Key over 255 charactersRead message; this is a client bug, not a transient fault
NOT_FOUND404No such account, person, job, or key in your organizationConfirm the identifier, and that it belongs to the key's organization
CONFLICT409State does not allow the operation, or an idempotency key was reused with a different bodyRe-read current state before retrying

Identity lifecycle

CodeHTTPMeaningWhat to do
KYC_REQUIRED403The Person has no approved KYC, and your organization requires it before this operationRun /v1/kyc/start and wait for approval before /v1/accounts/free
ACCOUNT_NOT_PROVISIONAL409The account is not in a lifecycle state this operation accepts — typically an unlock on an already-unlocked accountFetch GET /v1/accounts/{did} and check lifecycle; often the previous call already succeeded
NONCE_INVALID400Bind nonce missing, already spent, or expiredRequest a fresh /v1/bind/challenge; nonces are single-use
INVALID_SIGNATURE400The bind signature does not verify against the account's keyConfirm you signed payloadToSign verbatim with the key registered as ownerPublicKey
PERSON_ACCOUNT_CAP409The Person already holds the maximum bound accounts; details.max is the limitSurface it to the user rather than retrying

An unavailable account name is not an error: GET /v1/accounts/name-available returns 200 with {"available": false, "reason": "TAKEN"}. Check it before you offer a name to a user, and treat reason as a display hint rather than a failure.

Upstream and dependencies

CodeHTTPMeaningWhat to do
CHAIN_FAILURE502The chain write failed or could not be confirmed across RPC endpointsSafe to retry with the same Idempotency-Key; do not mint a second account
PROVIDER_FAILURE502A KYC/AML provider failed; message names whichRetry with backoff. Persistent failures are ours, not yours — quote the correlation ID
INTERNAL500Unhandled faultRetry idempotently with backoff; report with the correlation ID if it persists

Retrying

ClassRetry?
429Yes — after x-ratelimit-plan-reset seconds, with jitter
502, 500Yes — exponential backoff, and always with the original Idempotency-Key on billable endpoints
401, 403No — except a signing 401, where the fix is a freshly signed request, not a resend
400, 404, 409No — the request needs changing, not repeating

Retrying a billable endpoint without its original Idempotency-Key is how a retry becomes a double charge. See Idempotency.

See also

Errors · Identity Inc.