ReturnMate

Webhooks Reference

Receive signed, real-time notifications when offline repairs and trade returns change state in ReturnMate.

3 min read
Last updated 14 July 2026

ReturnMate sends outbound webhooks to your systems for RMAs that were created through the External API — offline repairs and trade returns. Webhooks are not emitted for standard portal- or staff-created returns.

Configuring a webhook endpoint

  1. Go to Settings → External API (Admin only).
  2. Create an API client, or edit an existing one, and set its Webhook URL (HTTPS recommended).
  3. Note the webhook secret shown when the client is created — deliveries are signed with it.

One endpoint per API client. Events for an RMA are delivered to the client that created it (trade-return events fall back to your shop's active client with a webhook URL).

Events

EventFired when
offline_repair.createdAn offline repair is created via the API
offline_repair.tracking_uploadedReturn tracking is lodged
offline_repair.status_changedThe repair moves between lifecycle stages
offline_repair.disposition_setA disposition is set at resolution
offline_repair.closedThe repair is closed
trade_return.createdA trade (B2B) return is created
trade_return.status_changedA trade return moves between lifecycle stages
trade_return.credit_requestedA credit is requested for a trade return
trade_return.resolvedA trade return is resolved

Payload

Deliveries are POST requests with a JSON body:

{
  "event": "offline_repair.status_changed",
  "timestamp": "2026-07-14T03:21:45.000Z",
  "data": {
    "id": "cln_…",
    "rmaNumber": "#WAR1234A",
    "externalRef": "TICKET-4821",
    "externalSource": "my-pos",
    "status": "OFFLINE_REPAIR"
  }
}

Every payload's data object includes the RMA id, rmaNumber, and your externalRef/externalSource, plus event-specific fields (for example the new status, tracking details, or the disposition).

Signature verification

If your client has a webhook secret, each delivery includes:

X-Webhook-Signature: <hex HMAC-SHA256 of the raw request body>

Verify it by computing HMAC-SHA256 over the raw request body with your webhook secret and comparing constant-time:

const crypto = require('crypto');

function verify(rawBody, signature, secret) {
  const expected = crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}
Use the raw body

Compute the HMAC over the exact bytes received, before any JSON parsing or re-serialisation, or signatures will not match.

Delivery, timeouts and retries

  • Requests time out after 10 seconds.
  • Respond with any 2xx status to acknowledge. Non-2xx responses and timeouts are retried.
  • Up to 4 attempts with backoff: immediately, then after 1 s, 4 s and 16 s. After the final failure the delivery is dropped (it is logged server-side but not exposed for replay).

Idempotency

Deliveries are at-least-once — your endpoint may occasionally receive the same event more than once (for example if your 2xx response was slow). De-duplicate on (event, data.id, timestamp) or on your own externalRef plus the event name, and make handlers idempotent.

Best practice

  • Acknowledge quickly (enqueue work, return 200) to stay inside the 10-second timeout.
  • Don't rely on webhook ordering; fetch the current state via GET /offline-repairs/:id when in doubt.
  • Rotate exposure by revoking and recreating the API client if a secret leaks.
Was this helpful?
Contact Support