Relevant Information for Claims APIs

This document describes the HTTP contract for the Merchant Claims API. Field names and merchant-facing statuses are aligned with the Tamara Partner Portal where applicable, so integrations can replace or complement portal workflows with a stable machine interface.

Claims APIs are available only for our sandbox environment currently.

Overview

The Claims APIs let a merchant:

CapabilityEndpoint
List claimsGET /claims
Get claim detailsGET /claims/{claim_id}
Accept a claimPOST /claims/{claim_id}/accept
Challenge a claimPOST /claims/{claim_id}/challenge
Download claim evidencePOST /claims/{claim_id}/generate-evidence-link
List store branchesGET /branches

All requests are scoped to the merchant identity in the access token.

Authentication

ItemTypeValue
SchemestringBearer token
HeaderstringAuthorization: Bearer <merchant_access_token> (required)
Token typestringMerchant API token
SituationHTTPerror_code
Missing or invalid token401unauthorized
Valid token that is not allowed to use this API as a merchant403forbidden

Optional mTLS gateway headers, when required by the token, are accepted and forwarded to payment services as needed:

HeaderTypeRequired
x-tamara-mtls-tokenstringNo
x-tamara-mtls-versionstringNo

Conventions


Content types

UseTypeContent-Type
JSON request bodiesstringapplication/json
Challenge with file uploadsstringmultipart/form-data

Data types

TypeMeaning
stringJSON string
integerJSON number with no fraction
numberJSON number, integer or decimal
booleantrue / false
objectJSON object
arrayJSON array of T
date-timestring, ISO-8601 / RFC 3339, e.g. 2026-09-22T10:15:30+00:00
datestring, YYYY-MM-DD
Moneyobject {amount: number, currency: string}
T or nullvalue of type T, or null

Money

FieldTypeDescription
amountnumberMajor units (e.g. 250.00 SAR)
currencystringISO 4217 currency code; for Accept refund_amount, it must match the claim currency

Dates and times

  • 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.

Pagination

List endpoints use page and limit.

ParameterTypeDefaultMaximumDescription
pageinteger1—Positive integer
limitinteger20Configurable; default ceiling 100Positive integer; values above the maximum are silently capped, not rejected

Idempotency

For accept and challenge, send:

Idempotency-Key:

HeaderTypeRequiredDescription
Idempotency-KeystringStrongly recommendedTrimmed; 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.

ScenarioBehaviour
Same key and same payload409 duplicate_request; the request is not replayed
Same key and different payload409 idempotency_key_reuse
Validation fails after key reservationThe key is spent; retry only with a new key
No keyRequest 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.


Merchant-facing claim statuses

StatusMeaning
openAwaiting merchant action
under_reviewWith Tamara, or awaiting further merchant settlement on a partial settlement
closedResolved: accepted, rejected, or otherwise closed
cancelledCancelled

Action rules

ActionAllowed when
ChallengeStatus is open
Accept / refundStatus 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

Error responses

FieldTypeDescription
error_codestringStable code, branch on this
messagestringHuman-readable, may change
detailsobjectAlways an object; empty is {}

Error Codes

error_codeHTTPWhen
unauthorized401Missing or invalid token
forbidden403Token is not a merchant token, merchant not found, merchant inactive, or a Checkout.com merchant calling Accept
invalid_parameter400Validation failure
invalid_refund_amount400Refund amount or currency rejected (currency mismatch returns empty details)
claim_not_found404Unknown claim or claim outside merchant scope
evidence_not_found404Evidence file is not available for the claim
claim_not_actionable409Claim cannot be challenged or accepted in its current status
idempotency_key_reuse409Same idempotency key used with a different payload
duplicate_request409Idempotency-Key already used with the same payload; read the claim to see the outcome
service_unavailable503Temporary outage or unsafe-to-complete operation
rate_limited429Reserved error code; may be emitted if a gateway adds rate-limit handling
internal_error500Unexpected server error

Details

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.

FieldTypeDescription
parameterstringinvalid_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_refundableMoneyinvalid_refund_amount — amount exceeds remaining claim
max_cancelableMoneyinvalid_refund_amount — cancel amount exceeds remaining cancelable order amount
jerk_error_codestringinvalid_refund_amount — payment service rejection
jerk_messagestringinvalid_refund_amount — payment service rejection
claim_statusstringclaim_not_actionable — current merchant-facing status

Shared schemas


Actor

FieldTypeDescription
actor_typestringmerchant, tamara, customer, system
namestringDisplay label; Tamara staff emails shown as "Tamara"

History row

FieldTypeDescription
claim_idstringClaim ID as string (differs from integer claim_id on the claim)
order_idstringOrder ID (UUID format)
statusstringMerchant-facing status for that row
commentstringEvent comment; may be "" (never null)
translated_commentarrayCurrently always []
created_atdate-timeISO-8601 timestamp
created_bystringmerchant or tamara
user_idstringCurrently always ""
metadataobjectEvent data; when empty it is sent as [] (not {})

Common metadata keys

FieldTypeDescription
actionstringaccept 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
requesterstringAlways on API-written rows; "" if not sent
attachmentsarrayChallenge rows, and oldest visible row when claim had files at creation
is_refundbooleanAccept that ran a refund (true)
refunded_amountMoneyAccept that ran a refund
canceled_amountMoneyAccept that ran a cancel
refund_reasonstringClosed 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.


Resolution and outcome fields

FieldTypeExample values
resolutionstringpending, refunded, merchant_won, cancelled, ""
sub_statusstringaccepted_by_merchant, rejected_by_merchant, refunded_from_tamara, refunded_from_merchant, ""
accepted_by / refunded_fromstring or nullmerchant, tamara, or null
winnerstringCLIENT, MERCHANT, or ""

Typical integration flows


Poll open claims and accept

  1. GET /claims?status=open
  2. GET /claims/{claim_id} to read the timeline and evidence names
  3. POST /claims/{claim_id}/generate-evidence-link as needed
  4. POST /claims/{claim_id}/accept with Idempotency-Key and refund_amount

Challenge with evidence

  1. GET /claims/{claim_id}
  2. POST /claims/{claim_id}/challenge as multipart/form-data with attachments[] and Idempotency-Key

Partial then full settlement

  • Refund settlement

  1. Accept less than the remaining claim → under_review
  2. Later Accept the remaining claim → closed
  • Cancel settlement

  1. Accept/cancel less than what finishes the order → under_review
  2. 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.


Rate limiting and availability

  • 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.