Skip to main content

Core concepts

Errors

Every error returns the same JSON shape with an HTTP status code repeated in the body. Status codes carry the meaning; the message explains the specific failure.

On this page

The error body

Errors return a JSON body of the form:

json
{ "code": 404, "message": "envelope not found" }
FieldTypeRequiredDescription
codeintegerOptionalHTTP status code, repeated in the body.
messagestringOptionalHuman-readable description of what went wrong.

Safe to surface

message is always safe to show an end user. Server internals — stack traces, SQL, upstream errors — are never echoed back in it.

Status codes

StatusMeaning
400Malformed request — missing required field, bad since format, disallowed target_url, unknown event_type.
401Missing, malformed, unknown, expired, revoked, or inactive API key.
404Object does not exist or belongs to another tenant. The two cases are deliberately indistinguishable.
406Business-rule rejection where no more specific status applies.
429Per-key rate limit exceeded.
500Unexpected server error. The response carries a generic message; internals are never echoed back.
503Service temporarily busy. Honor the Retry-After header.

404 and tenancy

A 404 means the object does not exist orit belongs to another tenant. The two cases are deliberately indistinguishable — distinguishing them would let a caller probe for the existence of other customers' envelopes.

Do not treat 404 as “deleted”

Because the two cases look identical, a 404 on an id you believe you created usually means the key belongs to a different account than the one that created it. Check with GET /api/v1/inkfree/me.

Retrying

429 and 503 are the two statuses worth retrying automatically. Back off before retrying a 429 — see Rate limits — and honor the Retry-After header on a 503.

4xx responses other than 429 will not succeed on retry; fix the request instead. If you are retrying envelope creation after a network timeout, use an idempotency key so the retry cannot create a second envelope.