Error handling
The /v1/rfi/** endpoints follow the standard gateway error envelope: an HTTP status, a stable
GatewayErrorCode, and a human-readable message (and optional details). The table below covers every
error class you may see from the RFI endpoints.
| HTTP | code | When you see it |
|---|---|---|
| 400 | VALIDATION_FAILED | Request body or path violated input validation — missing field, invalid UUID, empty answer string, etc. |
| 404 | NOT_FOUND | RFI, question or document request does not exist or is not accessible to your account. |
| 409 | CONFLICT | The RFI or item is in a state that does not permit the requested transition. See variants below. |
409 CONFLICT — two variants share the same code
GatewayErrorCode is intentionally status-flavoured and feature-agnostic — we do not introduce feature
specific codes. Both 409 variants share code = CONFLICT; partners distinguish them via the message (and
details when present) text.
| Variant | Trigger | Recovery |
|---|---|---|
RFI_NOT_OPEN | The whole case has reached a terminal state (CLOSED or CANCELLED). No further responses accepted. | None — the case is final. Fetch the case via GET /v1/rfi/{rfiId} to confirm the terminal status and stop polling. |
RFI_ITEM_ALREADY_APPROVED | The specific item (question or document request) is already approved and locked. | Skip the item — it is done. If you genuinely need to amend an approved item, contact support; the API does not unlock approved items. |
Match on the message (or details) substring — the canonical text contains the variant name (e.g. the
message for the first variant contains RFI_NOT_OPEN). Avoid string-matching on user-visible prose, which
may change.
404 vs 403 — cross-tenant requests
Requests for an RFI that belongs to a different account return 404 NOT_FOUND, not 403 FORBIDDEN.
This is deliberate: we do not leak the existence of resources outside your tenant. If you are confident the
rfiId should be visible to your AccountId and you still get a 404, check that you are passing the right
AccountId header.
Terminal-state behaviour summary
Once an RFI case reaches CLOSED or CANCELLED:
GET /v1/rfi/{rfiId}continues to work — the case is retained for audit.GET /v1/rfino longer lists it by default — passincludeTerminal=trueto include terminal cases.- All write endpoints (answer, attach, bulk responses) return
409 CONFLICT(RFI_NOT_OPEN). - No further
v1.rfi.case.*events fire for the case. - No further
v1.rfi.document.*events fire for documents attached to the case.
Retrying after an error
| Error | Safe to retry? |
|---|---|
400 VALIDATION_FAILED | Only after fixing the offending field — the same request will fail again. |
404 NOT_FOUND | Only after confirming the rfiId / questionId / documentRequestId and AccountId header. |
409 RFI_NOT_OPEN | No — terminal. |
409 RFI_ITEM_ALREADY_APPROVED | No — the item is done. |
| 5xx | Yes, with exponential backoff. Write endpoints are idempotent under replace semantics — answers replace answers, attach replaces the linked document. See Responding. |