Skip to main content

Overview

Webhooks deliver asynchronous notifications when events occur in the Return Helper system — for example, when a label is generated or a shipment arrives at the warehouse. Your server must expose an HTTPS endpoint to receive these POST requests.

Setting Up Your Webhook Endpoint

Endpoint Requirements

Before submitting a setup request, make sure your endpoint meets the following requirements:
  • Publicly accessible — the URL must be reachable from the internet (no VPN, localhost, or internal-only addresses)
  • HTTPS — the endpoint must be served over HTTPS with a valid TLS certificate
  • HTTP POST — the endpoint must accept POST requests with a application/json body
  • Respond HTTP 200 — your server must return a 200 OK status promptly after receiving the request; any other status code or a timeout is treated as a failed delivery
  • Fast response — process the event asynchronously if needed; do not perform heavy work before responding, to avoid delivery timeouts

Registering Your Endpoint

To register your webhook endpoint, please fill in the Webhook Setup Request Form. The form contains all the information we need to complete the setup quickly, and is the fastest way to get your endpoint activated.
We recommend using the form above, as it ensures all required details are captured in one step. If you are unable to use the form, you may also send the request by email — see the template below.
If you prefer to contact us by email, send the following to support@returnhelper.com:

Event Delivery

Timing — Events may arrive a few seconds after the triggering action, and in rare cases up to a few minutes later. Duplicate events — Your endpoint may receive the same event more than once. Track processed notificationId values to deduplicate; notificationId is unique per event and present on every webhook notification, so it is a stable idempotency key on its own. Event ordering — Delivery order is not guaranteed. Design your handler to process events in any order. For example, inventoryCreated may arrive before warehouseMarkShipmentArrivedV2. Use the API to fetch any objects referenced in events you receive out of sequence. Each event includes an eventTime field in ISO 8601 format.

Notification Headers

Every webhook request includes these headers:

Legacy headers

These headers are still sent on every notification and are not being removed. New integrations should read the headers above instead.
HTTP header names are case-insensitive, and some frameworks normalise them. The casing above is what Return Helper sends on the wire; if your framework lowercases incoming header names, match them case-insensitively.

Signature Verification

Always verify the signature before processing any payload. Use the raw request body — any transformation (e.g. by a framework that re-serialises JSON) will cause verification to fail.
Your signing key is provided by Return Helper (it is Base64-encoded). Store it securely and never expose it. You can find it in the User Portal on the same screen as your API key and token — see the screenshot under Authentication — or read it programmatically with Get signing key.

Worked Example

Given the following incoming request: Headers:
Body (raw JSON, must not be re-serialised):

Step-by-Step Verification

Step 1 — Extract the signature from the ReturnHelper-Signature header (for comparison at the end):
Step 2 — Extract the timestamp from the RETURNHELPER-TRIGGERED-AT header:
Step 3 — Build the string_to_sign Concatenate these four values in order (no separator):
  1. HTTP method: POST
  2. Your notification endpoint URL: https://s2024-01-12.free.beeceptor.com
  3. The RETURNHELPER-TRIGGERED-AT value from Step 2
  4. The raw JSON body
The resulting concatenated string:
Then Base64-encode the entire concatenated string. The result is the string_to_sign:
Step 4 — Compute the HMAC-SHA256 signature Using the example signing key (your actual key will be different):
Operations:
  1. Decode the string_to_sign (from Step 3) from Base64 → byte array
  2. Decode your signing key from Base64 → byte array
  3. Compute HMAC-SHA256 using the signing key bytes over the string_to_sign bytes → signature byte array
  4. Base64-encode the signature byte array
Expected result:
Step 5 — Compare signatures Compare the signature computed in Step 4 with the one extracted in Step 1. Use a constant-time string comparison to prevent timing attacks. Additional security: Reject events where eventTime differs from your system clock by more than 15 minutes (replay attack protection).

Sample Code

Retry Mechanism

Respond with a 2xx HTTP status code to acknowledge receipt. Non-2xx responses trigger retries. After 10 consecutive failures, notification delivery to your endpoint is suspended for 24 hours.

Common Body Fields

All notification bodies share these top-level fields:

Notification Event Reference


Notification Payloads

Label Result

Sent when a return label request completes (success or failure).
Always use shipmentId to match labels to shipments in your system — do not use labelId. In rare cases a carrier failure causes a new label (with a new labelId) to be issued for the same shipmentId.
category: labelGenerated / action: labelGenerated Key fields in label: Success example:
Failure example:

Warehouse Shipment Arrived (v2)

Sent when a warehouse marks a shipment received. Always followed by one or more Inventory Created events.
This event echoes your sellerReferenceNumber and is the primary reconciliation point between your order records and Return Helper’s identifiers. The V202207 default carries SRN at all three layers in one bundled payload; V202407 carries only the Shipment-layer SRN. See Seller Reference Number for the full reconciliation workflow and version differences.
category: rsl / action: markShipmentArrive / version: 202407 Key fields in shipment:

Inventory Created

Sent after a shipment is received (or a VAS split occurs) to notify that a new return inventory record has been created. One event is sent per inventory item — a single shipment may produce multiple events if multiple packages were received under the same label.
No sellerReferenceNumber in this payload. Neither returnInventory nor shipment carries sellerReferenceNumber; only shipment.referenceNumber is present, and that field echoes the orderNumber you supplied — not the seller reference. If you rely on sellerReferenceNumber to reconcile inventory back to your own records, do not subscribe to newInventoryCreated alone. Pair it with Warehouse Shipment Arrived (carries SRN at all three layers in V202207) or Inventory Handling Complete (carries the Line-Item SRN on returnInventory.sellerReferenceNumber). See Seller Reference Number for the full reconciliation strategy.
category: newInventoryCreated / action: newInventoryCreated Key fields in returnInventory:

Image Updated

Sent when images are added, changed, or removed for a return inventory line item. category: rrli / action: changeLineItemImage Top-level payload fields: Key fields in returnRequestLineItem:
URLs in imageUrlList are publicly fetchable, do not expire, and are safe to cache client-side. Persist them as-is. Empty state: imageUrlList: [].

Unknown Shipment Assigned

Sent when a shipment with no prior return request is identified and assigned to a seller. category: rsl / action: assignUnknown / version: 202407 Key fields in returnInventory: Key fields in unknownShipment:

Recall Status Update

Sent when a recall tracking number is updated or pick-up status changes. category: recall / action: recallUpdateStatus recallUpdateTypeStatus values:

Resend Status Update

Sent when a resend tracking number is updated or the resend completes or fails. category: resend / action: updateResendStatus Top-level payload fields: Key fields in resend: Key fields in each resendShipmentList entry:
resendShipmentList always contains exactly one entry — a resend has one and only one resend shipment. Read it as resendShipmentList[0].
trackingNumber is not a top-level field. It lives on the resend shipment: resendShipmentList[0].trackingNumber.
Check resend.resendStatusCode:
  • 3 — completed (read resendShipmentList[0].trackingNumber)
  • 4 — failed (read resendShipmentList[0].error)
Use resendShipmentList[0].sellerReferenceNumber to match the event to your own order record without storing Return Helper’s resendId.
sellerReferenceNumber only carries a value when the resend was created by an Enterprise account through Create resend by SKU with a reference supplied. It is null for every other resend. To look a resend up on demand by this value, use Search resend by seller reference number.

VAS Update

Sent when a value-added service completes. category: rrliv / action: vasUpdated Each item in updateVasList:
URLs in imageUrlList are publicly fetchable, do not expire, and are safe to cache client-side. Persist them as-is. Empty state: imageUrlList: [] (some VAS types do not produce photos; the entry remains in updateVasList[] with an empty array).

Inventory Handling Complete

Sent when a handling instruction (dispose, resend, recall, etc.) is completed by the warehouse. category: rinv / action: completeInventoryHandling Key fields in returnInventory: handlingCode values: handlingStatusCode values:

Inventory Recalibrated

Sent when a warehouse updates the measured dimensions or weight of a return inventory. category: completeRecalibrate / action: completeRecalibrate Key fields in recalibrateSupplement:

Inventory Meta Updated

Sent when a warehouse or user adds or updates metadata on a return inventory. category: updateReturnInventoryMeta / action: updateReturnInventoryMeta The payload contains returnInventory with the same structure as Inventory Created, including the updated returnInventoryMetaList. metaType values:
  • usr — user-supplied meta
  • whs — warehouse-supplied meta

RMA Updated

Sent when a warehouse corrects an incorrect RMA assignment. category: notifyUserRmaSwapped / action: notifyUserRmaSwapped Key fields in payload:

SKU Updated

Sent when a seller updates the SKU of a return inventory. category: userUpdateReturnInventorySku / action: userUpdateReturnInventorySku The payload contains returnRequest and returnInventory. Key fields in returnRequest: The returnInventory object follows the same structure as Inventory Handling Complete, with the updated sku field.

Split Line Item

Sent when a VAS operation splits a parcel into multiple inventories. Contains the new line item and inventory records for each resulting parcel. category: lineItemVasReturnInventoryLineItem / action: splitLineItem Top-level payload fields: Each item in splitLineItemAndReturnInventoryList contains:

Warehouse Remarks Updated

Sent when a warehouse updates remarks on a return request. category: warehouseUpdateWarehouseRemarks / action: warehouseUpdateWarehouseRemarks The payload contains three objects:
  • returnRequest — the return request (same structure as SKU Updated → returnRequest)
  • shipment — the shipment record with full address details, dimensions, weight, cost, and customFieldMap
  • returnInventory — the affected inventory (same structure as Inventory Handling Complete), with the updated warehouseRemarks field

Buyer Return Label Generated

Sent when a buyer creates a return in the Branded Return portal and a label is generated.
Only applicable to customers integrated with the Return Helper Branded Return service.
category: buyerReturnRrLabel / action: buyerReturnLabelGenerated Check buyerReturn.labelRequestStatusCode for "success" or "fail". Key fields in buyerReturn: Each item in buyerReturnLineItemList:

Shopify Buyer Return Created

Sent when a buyer creates a return request via Shopify integration. category: shopifyBuyerCreateReturn / action: shopifyBuyerCreateReturn Key fields in shopifyReturn: Each item in shopifyReturnLineItemList:

Consolidate Shipping Cost Updated

Sent when the shipping cost of a consolidated shipping order is updated. category: consolidateShippingOrderShippingFeeUpdated / action: consolidateShippingOrderShippingFeeUpdated Key fields in order:

Consolidate Shipping All Packed

Sent when a warehouse has packed all inventories into boxes for a consolidated order. category: consolidateShippingOrderInventoryAllPacked / action: consolidateShippingOrderInventoryAllPacked Key fields in order: Each item in shipmentList: Each item in boxList: Each item in consolidateShippingInventoryList:

Consolidate Shipment Sent

Sent when a warehouse dispatches a consolidated shipment to a carrier. category: consolidateShippingShipmentSent / action: consolidateShippingShipmentSent Key fields in shipment:

Consolidate Shipping AWB Updated

Sent when the Air Waybill number for a consolidated shipment is updated. category: consolidateShippingShipmentShipped / action: consolidateShippingShipmentShipped The shipment object follows the same structure as Consolidate Shipment Sent, with the updated awb field.

Consolidate Order Completed

Sent when all shipments in a consolidated order have been shipped. category: consolidateShippingOrderCompleted / action: consolidateShippingOrderCompleted The order object follows the same structure as Consolidate Shipping All Packed, including the full shipmentList with boxList and inventory details.

Consolidate Order Cancelled

Sent when a warehouse force-cancels a consolidated shipping order. category: consolidateShippingOrderCancelled / action: consolidateShippingOrderCancelled Key fields in order: