The Claims APIs let a merchant:
| Capability | Endpoint |
|---|
| List claims | GET /claims |
| Get claim details | GET /claims/{claim_id} |
| Accept a claim | POST /claims/{claim_id}/accept |
| Challenge a claim | POST /claims/{claim_id}/challenge |
| Download claim evidence | POST /claims/{claim_id}/generate-evidence-link |
| List store branches | GET /branches |
All requests are scoped to the merchant identity in the access token.
| Item | Type | Value |
|---|
| Scheme | string | Bearer token |
| Header | string | Authorization: Bearer <merchant_access_token> (required) |
| Token type | string | Merchant API token |
| Situation | HTTP | error_code |
|---|
| Missing or invalid token | 401 | unauthorized |
| Valid token that is not allowed to use this API as a merchant | 403 | forbidden |
Optional mTLS gateway headers, when required by the token, are accepted and forwarded to payment services as needed:
| Header | Type | Required |
|---|
x-tamara-mtls-token | string | No |
x-tamara-mtls-version | string | No |
| Use | Type | Content-Type |
|---|
| JSON request bodies | string | application/json |
| Challenge with file uploads | string | multipart/form-data |
| Type | Meaning |
|---|
| string | JSON string |
| integer | JSON number with no fraction |
| number | JSON number, integer or decimal |
| boolean | true / false |
| object | JSON object |
| array | JSON array of T |
| date-time | string, ISO-8601 / RFC 3339, e.g. 2026-09-22T10:15:30+00:00 |
| date | string, YYYY-MM-DD |
| Money | object {amount: number, currency: string} |
| T or null | value of type T, or null |
| Field | Type | Description |
|---|
amount | number | Major units (e.g. 250.00 SAR) |
currency | string | ISO 4217 currency code; for Accept refund_amount, it must match the claim currency |
- Response timestamps use ISO-8601 / RFC 3339, for example
2026-09-22T10:15:30+00:00.
- List filter dates may be sent as
YYYY-MM-DD or full timestamps.
- An end date given as a bare date includes the entire calendar day.
List endpoints use page and limit.
| Parameter | Type | Default | Maximum | Description |
|---|
page | integer | 1 | — | Positive integer |
limit | integer | 20 | Configurable; default ceiling 100 | Positive integer; values above the maximum are silently capped, not rejected |
For accept and challenge, send:
| Header | Type | Required | Description |
|---|
Idempotency-Key | string | Strongly recommended | Trimmed; maximum length 255 characters (longer → 400 invalid_parameter) |
Idempotency keys are single-use. The key is spent when processing starts. The API does not replay a previous success response.
| Scenario | Behaviour |
|---|
| Same key and same payload | 409 duplicate_request; the request is not replayed |
| Same key and different payload | 409 idempotency_key_reuse |
| Validation fails after key reservation | The key is spent; retry only with a new key |
| No key | Request is processed without replay protection |
For accept, the idempotency key is also used as the payment-side settlement idempotency identifier for both refunds and cancellations.
After any completed attempt — including 503 — do not expect the same key to run Accept or Challenge again (409).
Recovery: Call GET /claims/{claim_id} to see whether the claim already moved. If you need another attempt, use a new Idempotency-Key.
Recommendation: Always send Idempotency-Key for accept and challenge.
| Status | Meaning |
|---|
open | Awaiting merchant action |
under_review | With Tamara, or awaiting further merchant settlement on a partial settlement |
closed | Resolved: accepted, rejected, or otherwise closed |
cancelled | Cancelled |
| Action | Allowed when |
|---|
| Challenge | Status is open |
| Accept / refund | Status is open or under_review. The amount cannot exceed what is left on the claim; if nothing is left, the API returns 400 invalid_refund_amount with max_refundable = 0 |
| Field | Type | Description |
|---|
error_code | string | Stable code, branch on this |
message | string | Human-readable, may change |
details | object | Always an object; empty is {} |
error_code | HTTP | When |
|---|
unauthorized | 401 | Missing or invalid token |
forbidden | 403 | Token is not a merchant token, merchant not found, merchant inactive, or a Checkout.com merchant calling Accept |
invalid_parameter | 400 | Validation failure |
invalid_refund_amount | 400 | Refund amount or currency rejected (currency mismatch returns empty details) |
claim_not_found | 404 | Unknown claim or claim outside merchant scope |
evidence_not_found | 404 | Evidence file is not available for the claim |
claim_not_actionable | 409 | Claim cannot be challenged or accepted in its current status |
idempotency_key_reuse | 409 | Same idempotency key used with a different payload |
duplicate_request | 409 | Idempotency-Key already used with the same payload; read the claim to see the outcome |
service_unavailable | 503 | Temporary outage or unsafe-to-complete operation |
rate_limited | 429 | Reserved error code; may be emitted if a gateway adds rate-limit handling |
internal_error | 500 | Unexpected server error |
details may contain structured fields such as max_refundable or the offending parameter name. Please branch on error_code, not on the free-text message.
| Field | Type | Description |
|---|
parameter | string | invalid_parameter: offending field (e.g. refund_amount.amount); refund or cancel when the payment service rejected the settlement for a non-amount reason; order when the claim's order record is missing |
max_refundable | Money | invalid_refund_amount — amount exceeds remaining claim |
max_cancelable | Money | invalid_refund_amount — cancel amount exceeds remaining cancelable order amount |
jerk_error_code | string | invalid_refund_amount — payment service rejection |
jerk_message | string | invalid_refund_amount — payment service rejection |
claim_status | string | claim_not_actionable — current merchant-facing status |
| Field | Type | Description |
|---|
actor_type | string | merchant, tamara, customer, system |
name | string | Display label; Tamara staff emails shown as "Tamara" |
| Field | Type | Description |
|---|
claim_id | string | Claim ID as string (differs from integer claim_id on the claim) |
order_id | string | Order ID (UUID format) |
status | string | Merchant-facing status for that row |
comment | string | Event comment; may be "" (never null) |
translated_comment | array | Currently always [] |
created_at | date-time | ISO-8601 timestamp |
created_by | string | merchant or tamara |
user_id | string | Currently always "" |
metadata | object | Event data; when empty it is sent as [] (not {}) |
| Field | Type | Description |
|---|
action | string | accept for refunds and full cancels; challenge for challenges. Omitted on partial cancels that leave the claim under_review; those rows contain requester and canceled_amount instead |
requester | string | Always on API-written rows; "" if not sent |
attachments | array | Challenge rows, and oldest visible row when claim had files at creation |
is_refund | boolean | Accept that ran a refund (true) |
refunded_amount | Money | Accept that ran a refund |
canceled_amount | Money | Accept that ran a cancel |
refund_reason | string | Closed claims, when recorded |
The merchant API timeline does not return event_name or agent_name. Portal history may use different internal event names; merchants should interpret timeline entries using status, comment, and metadata.
| Field | Type | Example values |
|---|
resolution | string | pending, refunded, merchant_won, cancelled, "" |
sub_status | string | accepted_by_merchant, rejected_by_merchant, refunded_from_tamara, refunded_from_merchant, "" |
accepted_by / refunded_from | string or null | merchant, tamara, or null |
winner | string | CLIENT, MERCHANT, or "" |
Poll open claims and accept
GET /claims?status=open
GET /claims/{claim_id} to read the timeline and evidence names
POST /claims/{claim_id}/generate-evidence-link as needed
POST /claims/{claim_id}/accept with Idempotency-Key and refund_amount
Challenge with evidence
GET /claims/{claim_id}
POST /claims/{claim_id}/challenge as multipart/form-data with attachments[] and Idempotency-Key
Partial then full settlement
- Accept less than the remaining claim →
under_review
- Later Accept the remaining claim →
closed
- Accept/cancel less than what finishes the order →
under_review
- Later Accept/cancel enough to finish the order (
order_canceled + amount + order_captured ≥ order_total) → closed
Accepting only the remaining claim amount is not enough to close the claim if the order is still larger.
429 rate_limited is a reserved error code; no Claims API listener currently returns it. A gateway may add rate-limit handling.
- When the Claims API is temporarily disabled, responses use
503 service_unavailable.
- On
503, recover as advised here; do not reuse the Idempotency-Key.