Errors & rate limits

Platform-wide conventions — code against the shapes, not the prose.

Error envelope

{ "error": "MACHINE_CODE", "message": "Human-readable explanation", …context }

Status codes you'll meet

statuscodewhen
401UNAUTHENTICATED / INVALID_JWT / TOKEN_EXPIREDmissing, invalid or expired bearer — refresh and retry once
403FORBIDDEN / FIELD_ACCESS_DENIED / EMAIL_NOT_VERIFIEDRBAC, field ACLs, or an unverified account
404NOT_FOUNDalso returned for resources you may not see (no existence oracle — e.g. webhook hooks)
409SLUG_TAKEN / ALREADY_INSTALLEDidentity conflicts
422CERTIFICATION_FAILED / validation errorsstructured report or field list attached
428PERMISSIONS_NOT_ACKNOWLEDGED / SANDBOX_FIRSTinstall-governance gates — satisfy the precondition and retry
429BUDGET_EXCEEDED / rate limitshonor Retry-After; agents: the tenant's monthly token budget is spent
502INSTALL_FAILEDa downstream provision failed — the response lists what was rolled back

Rate limits

surfacelimit
Verification email resend3 / hour / account
Public form & hook intakesper-IP throttles on the CRM side
Your connector's upstreamdeclare connection.sync.rateLimitPerMinute; always back off on 429 (use the SDK's rateLimitedFetch)

Retry guidance