Errors & rate limits

Errors return a JSON body of the form { "code": "…", "message": "…" } with a matching HTTP status. Branch on code (stable), show message (human-readable) to operators.

StatusCodeWhen
401MISSING_CREDENTIALSNo API key or dashboard JWT supplied.
401INVALID_TOKENThe dashboard JWT is missing, malformed, or expired.
401INVALID_API_KEYThe API key is unknown, revoked, or IP-blocked.
403INSUFFICIENT_ROLEAuthenticated, but the org role lacks permission.
403INACTIVE_ORGThe organization is deactivated.
403CREDENTIAL_NOT_SHARED_WITH_ORGVerifying an org-scoped credential with no active, consented share.
402SUBSCRIPTION_REQUIREDA metered action while the subscription is canceled or unpaid. past_due is a grace window (not blocked).
402LAYER_SUBSCRIPTION_REQUIREDRegistering an agent without a live Trust Layer subscription. The 30-day Team plan trial satisfies it.
402TRUST_TRANSPARENCY_REQUIRES_SUBSCRIPTIONCreating a trust_transparency agent without an active Trust Transparency subscription (in addition to Trust Layer).
422FREE_EMAIL_DOMAIN / DISPOSABLE_EMAIL_DOMAINFREE_EMAIL_DOMAIN: creating a company account with a free-provider email — team accounts require a work domain (Personal accounts accept any non-disposable email). DISPOSABLE_EMAIL_DOMAIN: a disposable domain, refused for every account type.
409 / 410(transparency immutability)Attempting to change an agent's permanent verification_product after creation.
503PLAN_PRICE_NOT_CONFIGUREDCheckout for a plan whose Stripe price IDs are not configured on the deployment.
502CHECKOUT_FAILEDAn upstream Stripe API failure during checkout.

Consumer Delegation mint refusals use their own code vocabulary — see Consumer Delegation → Mint refusal codes.

Rate limits

Endpoints are rate-limited per API key. Verification and mutation endpoints carry tighter limits than reads to refuse flooding. A throttled request returns 429; back off and retry. Exact per-route limits are available to customers under their plan.