Skip to main content

Error codes

Every response uses a uniform envelope, so clients key on success rather than branching on HTTP status alone:

{ "success": false, "data": null, "error": { "code": "DISCUSSION_LOCKED", "message": "…" }, "meta": null }

Successful responses carry success: true and the payload in data (with pagination in meta).

Codes to handle

StatusCodeMeaning & action
400BAD_REQUESTMalformed input. Fix the request.
401UNAUTHORIZEDMissing/invalid API key, or an identity assertion that failed to verify. See Identity signing → debug.
403IDENTITY_VERIFICATION_REQUIREDDeployed tenant has no signing secret, or no assertion was sent. Mint a secret and sign.
403FORBIDDENThe key/principal lacks the required capability.
403DISCUSSION_LOCKEDWrite attempted on a locked discussion.
403EDIT_WINDOW_EXPIREDComment edit attempted past its edit window.
404NOT_FOUNDNo such resource — expected when reading a discussion before its first comment.
409CONFLICTUniqueness violation (e.g. duplicate report); IDEMPOTENCY_IN_PROGRESS for an in-flight retry.
422UNPROCESSABLE_ENTITYSyntactically valid but violates a business rule (e.g. reply past max depth); also idempotency-key body mismatch.
429TOO_MANY_REQUESTSRate limited — honour the Retry-After header.
5xxINTERNAL / SERVICE_UNAVAILABLETransient — retry with backoff.

Why 401 vs 403 IDENTITY_VERIFICATION_REQUIRED are split

They answer different questions: 403 IDENTITY_VERIFICATION_REQUIRED means "this tenant isn't configured for verified identity yet" (mint the secret), while 401 means "you sent an assertion and it didn't verify" (fix your signing). Branch on the code, not the message — messages may change, but codes are part of the versioning contract.