DDuvappsDocumentationStudio

Errors and limits

Stable codes, and two different kinds of stop.

Codes

Switch on error.code, never on prose. The codes are stable across versions.

CodeHTTPMeans
unauthenticated401No usable credential
forbidden403Your permissions do not cover this
not_found404No such thing, or none you can see
validation_failed422The request is wrong, and the message says which parameter or key
conflict409Something changed underneath you
rate_limited429Too many sign-in or OAuth attempts: wait a minute and retry
payment_required402Out of credit: waiting will not help

Saved with warnings

Email, URL and phone fields preserve the supplied text. A suspect format still succeeds; record create/update responses include a warnings array withcode: suspect_format, recordId, fieldId,fieldName and message. Only visible fields and rows are included. An empty array means no visible format warning. Do not retry a successful write because it contains warnings. Format checks do not verify that an address exists.

Invalid numbers, impossible dates, invalid choices and values exceeding their limits fail with validation_failed (422). Send numbers or numeric strings and ISO dates such as 2026-09-22; timestamps must include a timezone. A failed create batch saves none of its rows. SQL updates can partially succeed and return failures and warnings.

Why 402 and 429 are different

Rate limits are about speed and clear on their own. Spend limits are about money and do not. Conflating them means someone who has run out of credit is told to wait, and waits forever.

Today the only rate limits are on signing in and on the OAuth endpoints, which answer 429 after too many attempts from one address in a minute. The /v1 API itself has no request rate limit yet; if one is added it will answer 429 with a Retry-Afterheader, and a well-behaved client already handles that.

What an error never contains

The name of a field you cannot read. "You cannot read salary" tells you a field called salary exists, which is exactly what the rule was hiding. Errors name the operation, not the thing being protected.