Webhook Overview

This specification describes how AfterShip Returns sends webhook events. You can implement your webhook callback endpoint accordingly.

When a "return" is created or updated in the AfterShip Returns (i.e. a customer has submitted a return request), the system will emit a corresponding event by sending an HTTP POST payload to the webhook's configured URL. (Updates include only the returns of your own connected stores in AfterShip Returns).

You can receive any field update by simply listening the the following events:

  • return.created: Occurs when a return request is successfully submitted
  • return.updated: Occurs whenever any field of a return request is updated.

There are also a few other events in smaller granularity that you can subscribed to, in case you want less amount of event updates:

graph TD; subgraph returnupdated["return.updated"] return.approved return.shipment.created return.shipments.created return.shipment.updated end return.created-->return.approved return.approved--single label ready-->return.shipment.created--all labels ready-->return.shipments.created return.shipments.created--logistics status update-->return.shipment.updated

This table list out the most common usages of the webhooks.

Return Life CycleWebhook EventCritical Payload Fields
RMA submitted.return.createdstatus=submitted
RMA approved, labels not yet generated.return.approvedstatus=approved
A single RMA label was generated/uploaded.return.shipment.createdshipments[0].label, shipments[0].tracking_number
RMA labels were fully generated/uploaded.return.shipments.createdshipments[x].label, shipments[x].tracking_number
A single RMA label was scanned by its carrier.return.shipment.updatedshipments[0].tracking_status=InStransit
Return items of a single RMA label got delievered to return location.return.shipment.updatedshipments[0].tracking_status=Delivered
  • return.shipment.updated: Occurs when a return shipment status is updated, e.g. moved to inTransit or Delivered state.

If you use a parcel collection network provider such as Happy Returns/Hubbed to receive return items. Events below apply.

  • return.dropoff.created: Occurs when a drop-off parcel QR code is generated for shoppers to take the items and drop them off at the parcel collection location.
  • return.dropoff.updated: Occurs when a drop-off parcel is updated, e.g. when it is handed over to parcel collection location.
  • return.dropoff.shipment.updated: Occurs when shipment statuses of drop-off items update, usually happens when the items are packed by the parcel collection provider and shipped to the warehouse of merchants. This shipment is outside the tracking scope of AfterShip but purely managed by the parcel network provider.

Please check out the detailed payload on this page.


  1. Ennable the webhook by visiting webhook configuration page. At the top right corner, switch to the organization you want to configure.

  2. Fill in the form and save your webhook configuration. You will then see a secret at the configuration page. The secret is for you to verify that the sender is from AfterShip following this implementation later on. Now to test out the webhooks, either submit a new return request or edit the notes on existing RMAs, webhooks then fires immediately.

The webhook enum values are not restrictive and may be extended with more options as the product evolves. To avoid accidental crashes in your webhook integration, please do not define restrictive, fixed enum options in your code. Instead, treat the enum as just a string in your program and be prepared for the possibility of new kinds of values appearing in the future.

We provide a few options for you to securely verify that the sender is from AfterShip.

We currently support only HTTPS URLs, so you can have security by using an SSL-enabled URL. But keep in mind that your endpoint is going to be wide-open on the Internet, and you might not want others to be able to submit random data to your systems. At this time, please aside from trying to keep the URL private. We advise you to simply include a secret key in the URL that you can use to check the secret GET parameter in your scripts.

Retry Webhooks

The webhook receiver shall respond with a 2xx status code. In case of an unsuccessful event (HTTP response code NOT between 200 and 299), AfterShip attempts to deliver your webhooks up to 14 times with exponential backoff.

The attempted webhook delay is calculated by this formula:

2^(number of retries) x 30 seconds

# of attempt# of retryDelay (sec) before send outAcc. Delay (sec)
1000
213030
326090
43120210
54240450
65480930
769601890
8719203810
9838407650
109768015330
11101536030690
12113072061410
131261440122850
1413122880245730

For example,

If the attempt fails, AfterShip will retry the 2nd attempt 30 seconds later.
If the 7th attempt fails, AfterShip will retry the 8th attempt 960 seconds later.
If the 14th attempt fails, AfterShip will no longer send out that webhook.