We're software that helps growing brands & retailers grow and scale. Sync, sell and ship your products and inventory on online marketplaces and storefronts faster, easier and more accurately.

Learn more now

Webhook Events & Payload Reference

Overview

This reference covers the technical details of SureDone webhook payloads — what you'll receive at your endpoint, how events are structured, and how to verify their authenticity. For setup instructions, see Getting Started with Webhooks.


Additional documentation can be found here and here


Payload Format (CloudEvents 1.0)

All webhook payloads follow the CloudEvents 1.0 specification — an industry standard for describing event data. Every delivery to your endpoint will have a JSON body structured like this:

{
  "specversion": "1.0",
  "type": "suredone.order.created",
  "source": "/suredone/users/12345",
  "id": "evt_a1b2c3d4e5f6a1b2c3d4e5f6",
  "time": "2026-02-19T15:30:45.123456Z",
  "datacontenttype": "application/json",
  "data": {
    "oid": "98765",
    "channel": "ebay1",
    "status": "READY",
    "resource_type": "order",
    "resource_id": "98765"
  }
}

Envelope Fields

FieldDescription
specversionAlways "1.0" (CloudEvents version).
typeThe event type, prefixed with suredone. (e.g., suredone.order.created).
sourceIdentifies the SureDone account: /suredone/users/{user_id}.
idA unique event ID (format: evt_ followed by a 24-character hex string). Use this for idempotency — see Handling Duplicates below.
timeISO-8601 UTC timestamp of when the event occurred (microsecond precision).
datacontenttypeAlways "application/json".
dataThe event-specific payload (see below).

Event Types & Data Fields

The data object contains different fields depending on the event type. All event types include resource_type and resource_id.

order.created

Fired when a new order is imported into SureDone from any sales channel.

"data": {
  "oid": "98765",
  "channel": "ebay1",
  "status": "READY",
  "resource_type": "order",
  "resource_id": "98765"
}

order.updated

Fired whenever any field on an existing order is modified. This event fires on every order edit, in addition to any more specific events (like order.status_changed or order.fulfilled).

"data": {
  "oid": "98765",
  "channel": "ebay1",
  "status": "SHIPPED",
  "resource_type": "order",
  "resource_id": "98765"
}

order.status_changed

Fired when an order's status field changes. Includes the previous status so you can track the transition.

"data": {
  "oid": "98765",
  "channel": "ebay1",
  "status": "SHIPPED",
  "previous_status": "READY",
  "resource_type": "order",
  "resource_id": "98765"
}

order.fulfilled

Fired the first time an order's shipping status transitions to Partial or Complete. Includes tracking information when available.

"data": {
  "oid": "98765",
  "channel": "ebay1",
  "status": "SHIPPED",
  "tracking_number": "1Z999AA10123456784",
  "ship_carrier": "UPS",
  "resource_type": "order",
  "resource_id": "98765"
}

Note: If tracking number or carrier is empty, those fields will be omitted from the payload. This event fires only on the first fulfillment transition — if an order goes from Partial to Complete, the event does not fire again.

Multiple Events per Operation

A single order edit can trigger multiple webhook events. For example, if you update an order and change its status to "SHIPPED" with tracking info, you could receive up to three events from that one operation:

  1. order.updated — always fires on any edit
  2. order.status_changed — because the status changed
  3. order.fulfilled — because shipping status transitioned to Partial/Complete

Each event has its own unique id, so they won't be deduplicated against each other. Your system should be prepared to receive multiple events for the same order in quick succession.

Thin Payloads

Webhook payloads are intentionally lightweight — they contain key identifiers and status information, but not the full order object. This design keeps deliveries fast and reliable.

To get complete order details, use the order ID (oid) from the webhook to fetch the full order via the SureDone API:

GET https://api.suredone.com/v3/orders/{oid}

Signature Verification

Every webhook delivery includes three headers you can use to verify authenticity:

HeaderDescription
webhook-idUnique message identifier (consistent across retries of the same delivery).
webhook-timestampUnix timestamp (seconds since epoch) of when the webhook was sent.
webhook-signatureHMAC-SHA256 signature(s) for verification.

How to verify

  1. Get your secret key: Take the signing secret you saved when creating the endpoint (starts with whsec_). Strip the whsec_ prefix and Base64-decode the remainder to get the raw key bytes.
  2. Build the signed content: Concatenate the webhook-id, webhook-timestamp, and raw request body with periods as separators:
    {webhook-id}.{webhook-timestamp}.{raw_body}
  3. Compute the signature: Calculate an HMAC-SHA256 of the signed content using the decoded secret key, then Base64-encode the result.
  4. Compare: The webhook-signature header contains one or more signatures in the format v1,{base64_signature} (space-separated). Compare your computed signature to each one using a constant-time comparison function.
  5. Check timestamp: Optionally, verify that webhook-timestamp is within a few minutes of your server's current time to protect against replay attacks.

Use the raw request body exactly as received — do not re-serialize or modify whitespace before computing the signature.

For ready-made verification libraries in multiple languages, see the webhook verification documentation which is compatible with SureDone's webhook signatures.

Retry Behavior

If your endpoint doesn't return a 2xx HTTP status code (200-299) within 15 seconds, the delivery is considered failed and SureDone will retry with exponential backoff:

AttemptDelay
1st retry~5 seconds
2nd retry~5 minutes
3rd retry~30 minutes
4th retry~2 hours
5th retry~5 hours
6th retry~10 hours
7th retry~10 hours

After 8 total attempts (1 initial + 7 retries), the delivery is marked as Failed. You can manually retry failed deliveries from the delivery logs in the UI.

Automatic disabling: If all deliveries to an endpoint fail continuously for 5 days, the endpoint will be automatically disabled. You can re-enable it from the Webhooks settings after resolving the issue with your server.

Handling Duplicates (Idempotency)

While SureDone makes every effort to deliver each event exactly once, in rare cases the same event may be delivered more than once. This can happen due to network issues, retries, or edge cases in message processing.

To handle this safely:

  1. Extract the id field from the CloudEvents payload (e.g., evt_a1b2c3d4e5f6a1b2c3d4e5f6).
  2. Before processing, check whether you've already handled an event with this ID.
  3. If you have, skip it. If not, process it and record the ID.

The event ID is stable across retries — the same event will always have the same id, so this approach reliably prevents duplicate processing.

Best Practices Summary

  • Return 200 quickly — Accept the webhook and return a 2xx response within 15 seconds. Do heavy processing in a background job.
  • Implement idempotency — Track event IDs to safely handle duplicate deliveries.
  • Verify signatures — Use HMAC-SHA256 verification to confirm webhooks are from SureDone.
  • Use webhooks + polling together — For critical workflows, supplement webhooks with periodic API polling as a safety net to catch any events that might have been missed after all retry attempts.
  • Fetch full data via API — Webhook payloads are lightweight notifications. Use the SureDone API to retrieve complete order details when needed.
  • Monitor endpoint health — Check the Statistics dashboard and endpoint health badges regularly. Investigate degraded or failing endpoints promptly.