API errors

Every error the Partner API returns is an RFC 7807 application/problem+json body:

{
  "type": "https://docs.rostergiving.com/errors/bad-request",
  "title": "Bad Request",
  "detail": "church_id is required",
  "request_id": "req_1a2b3c..."
}

type links to the pages below. Always log request_id — it is how support correlates your call with our traces. Every response to an authenticated call, success included, carries the same reference in the X-Request-Id header, so you can log it for every call your key makes.

Some errors come from the gateway in front of the API, not from the API itself: its throttle, shared by every partner (429), or a call the API did not answer in time (500 or 503). They are plain JSON, such as {"message":"Too Many Requests"}, with no type, no request_id and no Retry-After. Retry them with exponential backoff, starting at about one second, and the same Idempotency-Key. Log the UTC time and the operation (method and path) and include both when you write to support; these responses carry no request_id.

The gateway also answers two requests that never reach the API. A path it cannot parse, such as one containing %zz, gets 400 with an HTML body: fix how you build the URL, and do not retry it unchanged. A browser preflight (OPTIONS) gets 403 with an empty body: the API takes calls from your backend, not from a web page.

None of these gateway responses carries X-Request-Id, Roster-Api-Version or RateLimit-*, so there is no X-Request-Id to log for them. Every response the API itself sends carries X-Request-Id and Roster-Api-Version.

Code When
bad-request Request rejected before any effect
unauthorized Key missing, malformed, unknown or wrong mode
not-found Resource absent for your key
conflict Request contradicts current state
gone Hosted-flow token expired or already used, or opened from a site not in your allowed origins
rate-limited Per-partner quota exceeded this minute — retry after Retry-After
church-intake-paused New church registration paused for your account — existing churches and their donations continue
church-already-verified Church verification resubmitted for a church Roster already verified — treat it as done
idempotency-key-reused The key belongs to another body on this operation — nothing ran
amount-exceeds-refundable A refund asked for more than what is left of the donation — no refund was created
donation-in-flight The donation is being sent to the church's bank — repeat the refund request in a few minutes
donor-sessions-not-open Donor sessions are not open in this environment yet — nothing was created
refund-not-cancelable The refund can no longer be canceled — nothing changed
internal Our fault — retry with the same Idempotency-Key
bad-gateway A sandbox simulator could not reach our webhook receiver — retry later
unavailable The operation is not enabled in this environment