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.