React to claim updates

Keep your records in sync with every claim status change using the CLAIM_UPDATE webhook.

Mulberry sends a CLAIM_UPDATE webhook to your claim_update_url every time a claim's status changes, so you can mirror the claim lifecycle in your own system without polling. This page is the operational recipe: receive the event, verify it, correlate it to your records, update your state, and acknowledge.

A CLAIM_UPDATE also arrives when a claim is auto-closed

CLAIM_UPDATE fires on any status change — including the system auto-closing a claim because its underlying order was cancelled. That arrives with status CLOSED and reason CLOSED_CANCELLED_BY_CUSTOMER. Don't assume auto-closures are silent: handle a CLOSED event the same way whether a human or the system triggered it. See Cancel a warranty.

For the CLAIM_UPDATE payload shape, signing, headers, and retry behavior, this page links to the Webhook catalog rather than repeating them — that page is the single source of truth for the contract. Here we cover only what you do with the event.

Prerequisites

Before you can react to claim updates, confirm:

  • Your claim_update_url is configured and webhook delivery is enabled for your account. See Configuration.
  • You have your mulberry_access_token — the HMAC signing secret. See Get your credentials.
  • You registered the sale with your own order ID, so incoming events can be matched back to it. See Register the sale.
  • Your endpoint captures the raw request body before any JSON middleware touches it (required to verify the signature).

React to a claim update

  1. Receive the POST at your claim_update_url. Each delivery carries the headers and JSON body documented in the Webhook catalog. The X-Webhook-Topic header is CLAIM_UPDATE.

    You should now have the raw request body and the request headers in hand.

  2. Verify the signature before trusting anything in the payload. Recompute the HMAC-SHA256 over the raw body with your mulberry_access_token and compare it against X-Signature-SHA256 using a constant-time comparison. See Verify the signature for the exact procedure and code examples.

    On a match, the request is authentic — continue. On a mismatch, respond 401 and stop; do not process the payload.

  3. Correlate the event to your records. Match the claim by data.claim.id (the claim UUID), and tie it back to the order you registered using data.claim.order.external_order_id — that is the order ID you supplied. (data.claim.order.id is Mulberry's internal order ID, not yours.)

    You should now have resolved the event to a specific claim and order in your own system.

    • The first CLAIM_UPDATE you see for a claim may arrive before you've recorded the claim locally — upsert on data.claim.id rather than assuming the record already exists.
    • Deliveries can repeat. Deduplicate on the X-Idempotency-Key header (the event's event_id) so reprocessing is harmless. See Retries.
  4. Update your records from the partner-facing status in data.claim.status. Branch on this published subset:

    statusWhat it meansTypical action
    SUBMITTEDThe claim was filed and receivedOpen/record the claim
    UNDER_REVIEWMulberry is adjudicating the claimMark it in progress
    APPROVEDThe claim was approved for a resolutionRecord the outcome; check reason, payout_amount, and issued_replacement
    DENIEDThe claim was not approvedClose it as denied
    RESOLVEDThe claim's resolution is completeMark it resolved
    CLOSEDThe claim is closed (including order-cancellation auto-close)Close it; inspect reason

    The supporting fields refine an APPROVED outcome: reason is an opaque classification string (e.g. FINANCE_APPROVED_REPLACEMENT), payout_amount is the settlement amount when one applies, and issued_replacement is true when the resolution is a replacement unit. reason and payout_amount are null until they apply.

    You should now have your local claim record reflecting the new status.

    🚧

    Treat unknown statuses as forward-compatible

    The six statuses above are the published partner subset, but Mulberry's internal lifecycle has more. If you receive a status you don't recognize, don't error or reject the event — acknowledge it and either ignore it or fall through to a safe default. Branch only on the values you know.

    📘

    reason is a string, not an enum to switch on

    Treat reason as a human-readable label for logging and display. New reason values are added over time, so don't hard-code branching logic against the full set — branch on status, and read reason / payout_amount / issued_replacement as detail.

  5. Acknowledge with a 2xx. Once you've durably recorded the update, return any 2xx. That is the entire success contract for CLAIM_UPDATE — unlike CLAIM_REPLACEMENT, no response body is required.

    Mulberry treats any non-2xx (or a timeout) as a failed delivery and may retry it with exponential backoff if max_retries is set. See Retries.

    The event is now acknowledged and will not be retried.

👍

Keep the handler thin and fast

Verify, correlate, persist the status, return 2xx — and do heavier work (notifications, fulfillment routing) asynchronously. Replacements are driven by a separate CLAIM_REPLACEMENT webhook with its own confirmation contract; don't try to trigger fulfillment from a CLAIM_UPDATE. See the Webhook catalog.

Related