Setting Up Order and Tracking Webhooks
A guide to setting up automated, real-time HTTP POST notifications for your orders and shipments.
Webhooks let Spark Shipping push real-time notifications to an external endpoint of your choosing as orders move through fulfillment. Instead of polling the API, your systems receive an HTTP request the moment a key event occurs.
Two webhooks are available, and each can be used independently:
- Orders Webhook — fires when a FulfillmentRequest is created, i.e. when Spark Shipping routes an order (or part of an order) to a Vendor for fulfillment. The payload describes the FulfillmentRequest.
- Push Tracking Webhook — fires after tracking for a Shipment has been successfully sent back to the store/sales channel. The payload describes the Shipment.
Common uses include mirroring fulfillment activity into an ERP or warehouse system, logging shipments, and triggering downstream automations.
Note: Webhooks require the API Access feature on your site. If the fields described below are not visible for you, contact Spark Shipping support to enquire about getting that enabled.
Setting Up a Webhook
- Navigate to Site → Advanced Options.
- Locate the Orders Webhook URL and Push Tracking Webhook URL fields.
- Enter the URL of your receiving endpoint into either field (or both) and save.
A webhook is active as soon as a URL is saved, and is disabled by clearing the field. The two webhooks are configured separately, so one can be used without the other.
Your endpoint should:
- Accept an HTTP POST with a JSON body (
Content-Type: application/json). - Use an https:// URL. TLS is applied automatically for HTTPS endpoints.
- Respond promptly with a 2xx status code.
Delivery Behavior
A few characteristics of webhook delivery are important to account for when building an endpoint:
- Delivery is asynchronous. Notifications are queued and sent shortly after the triggering event (approximately 10 seconds later), rather than synchronously at the moment of the event.
- Notifications are not retried. If an endpoint is unreachable, times out, or returns a non-2xx status, the request is not re-sent. Failures are logged on the Spark Shipping side, but webhooks should be treated as best-effort notifications.
- Requests are not signed. There is no HMAC signature, authentication header, or shared secret on the request. To verify authenticity, use a hard-to-guess endpoint URL (for example, one containing a random token) and/or confirm the contents against the Spark Shipping API.
- Request format. All webhooks are delivered as an HTTP POST with
Content-Type: application/jsonand the JSON document described below as the body.
Orders Webhook Payload
Sent when a FulfillmentRequest is created. Top-level fields:
| Field | Type | Description |
id |
Integer | The FulfillmentRequest ID in Spark Shipping |
order_id |
Integer | Spark Shipping's internal Order ID |
order_uuid |
String | The order number from the store/sales channel (e.g. #1001) |
vendor_name |
String | The Vendor the request was sent to |
fulfillment_request_batch_id |
Integer | The batch this request belongs to |
created_at / updated_at |
DateTime (ISO 8601) | Timestamps |
fulfillment_request_items |
Array | The line items being fulfilled |
vendor |
Object | Vendor details (id, name, timestamps, and nested site) |
Each entry in fulfillment_request_items includes the values stamped at fulfillment time — id, order_item_status_name, stamped_vendor_sku, stamped_vendor_cost, stamped_product_name, stamped_product_sku, stamped_primary_image, stamped_datasource_barcode, and stamped_product_user_field_1 through _10 — along with nested vendor_sku, product, and order_item objects.
Example Payload
{
"id": 12345,
"order_id": 98765,
"order_uuid": "#1001",
"vendor_name": "Acme Distribution",
"fulfillment_request_batch_id": 5555,
"created_at": "2026-05-26T10:30:00Z",
"updated_at": "2026-05-26T10:30:00Z",
"fulfillment_request_items": [
{
"id": 111,
"order_item_status_name": "Complete",
"stamped_vendor_sku": "VEND-SKU-001",
"stamped_vendor_cost": "12.50",
"stamped_product_name": "Blue Widget",
"stamped_product_sku": "STORE-SKU-001",
"stamped_primary_image": "https://example.com/widget.jpg",
"stamped_datasource_barcode": "012345678905",
"stamped_product_user_field_1": null,
"vendor_sku": { "id": 9001, "sku": "VEND-SKU-001", "cost": "12.50", "...": "..." },
"product": { "id": 4321, "sku": "STORE-SKU-001", "...": "..." },
"order_item": {
"id": 7777,
"datasource_item_id": "123456",
"quantity_ordered": 2,
"price": "29.99",
"order_item_status": "Complete",
"product": { "...": "..." }
}
}
],
"vendor": {
"id": 1,
"name": "Acme Distribution",
"created_at": "2025-01-15T00:00:00Z",
"updated_at": "2026-05-01T00:00:00Z",
"site": { "...": "..." }
}
}
Because each item embeds full vendor_sku, product, and order_item objects, this payload can be large. Read the fields needed by key and ignore the rest.
Push Tracking Webhook Payload
Sent after tracking for a Shipment is successfully sent back to the store/sales channel. Top-level fields:
| Field | Type | Description |
id |
Integer | The Shipment ID in Spark Shipping |
order_id |
Integer | Spark Shipping's internal Order ID |
order_datasource_increment_id |
String | The order number from the store/sales channel (e.g. 1001) |
vendor_id |
Integer | The Vendor that shipped the items |
carrier |
String | Shipping carrier (e.g. UPS, FedEx) |
shipment_method |
String | Shipping method (e.g. Ground 3 Day) |
tracking_number |
String | The tracking number |
shipping_cost |
String | The cost of the shipment |
vendor_name |
String | The Vendor name |
created_at / updated_at |
DateTime (ISO 8601) | Timestamps |
shipment_order_items |
Array | Items in the Shipment (id, quantity, sku, shipping_cost) |
vendor |
Object | Vendor details (id, name, timestamps, and nested site) |
Example Payload
{
"id": 54321,
"order_id": 98765,
"order_datasource_increment_id": "1001",
"vendor_id": 1, "carrier": "UPS",
"shipment_method": "Ground 3 Day",
"tracking_number": "1Z999AA10123456784",
"shipping_cost": "12.50",
"vendor_name": "Acme Distribution",
"created_at": "2026-05-26T11:00:00Z",
"updated_at": "2026-05-26T11:00:00Z",
"shipment_order_items": [
{ "id": 222, "quantity": 2, "sku": "STORE-SKU-001", "shipping_cost": "2.99" }
],
"vendor": {
"id": 1,
"name": "Acme Distribution",
"created_at": "2025-01-15T00:00:00Z",
"updated_at": "2026-05-01T00:00:00Z",
"site": { "...": "..." }
}
}
Common Questions
How do I match a webhook back to an order in my store?
Use order_uuid (Orders Webhook) or order_datasource_increment_id (Push Tracking Webhook). These hold the order number from the store/sales channel. The order_id field is Spark Shipping's internal identifier, not the store's order number.
What happens if my endpoint is down when an event occurs?
The notification is not retried or queued for later delivery. Webhooks are best-effort, so endpoints should be highly available, and the Spark Shipping API can be used to reconcile any missed events.
How do I verify that a request actually came from Spark Shipping?
Requests are not signed. The recommended approach is to use a non-guessable endpoint URL (for example, one that includes a random token) over HTTPS, and to validate the payload contents against the API where verification is critical.
Can I change the payload format or choose which fields are sent?
No. The payload is generated from Spark Shipping's standard API entities and is not configurable. New fields may be added over time, so endpoints should parse defensively and ignore unrecognized fields.
Why didn't my webhook fire immediately?
Delivery is asynchronous and occurs a short time after the event (approximately 10 seconds), so a brief delay is expected.