Webhooks allow app developers to be notified, in near real-time, when specific events occur on a BigCommerce store. For example, your app may need to perform an action when a new order is created, a product’s inventory decreases, or an item is added to a shopper’s cart. When a subscribed event occurs on a store, BigCommerce will POST a payload to your app’s callback URI so your app can take some action based on that event.

Multiple Events Are Triggered during Bulk Data Imports

Bulk data imports will trigger the relevant events for every record affected. For example, if you have a hook on store/product/created, when the merchant imports 2,000 products, we will send 2,000 individual callback events.


Authentication

Webhooks are authenticated using Oauth and support the JSON media type. Basic auth and XML are not supported.

Before you can begin to send and receive requests, you must have the following:

  • A store: You can get a sandbox store by joining the Partner Program.
  • OAuth Client ID: Obtained by creating an API Account.
  • OAuth token: Obtained by creating an API Account.
  • Valid TLS/SSL configuration: Verify your app server’s setup at the following site: https://sslcheck.globalsign.com
Connection Breakers

Any one of the following conditions on your app server will cause a connection failure:

  • Hostname/DNS mismatch.
  • Self-signed certificate.
  • Intermediate certificates not loaded.

Lightweight Callback Payload

When a subscribed event occurs, we send a light payload with only minimum details regarding the event that’s been triggered. This gives you maximum flexibility as to how you want to handle the notification in your application. For instance, if you subscribe to the store/order/statusUpdated event, we’ll send you the order ID when the status is updated. You might want to handle the notification by fetching the full order details via a request to the Orders resource.

An example payload follows:

{
 "store_id":11111,
 "producer":"stores/abcde",
 "scope":"store/order/statusUpdated",
 "data":{
         "type":"order",
         "id":173331
        },
 "hash":"3f9ea420af83450d7ef9f78b08c8af25b2213637"
 }
Name Definition
store_id A numerical identifier that is unique to each store.
producer Will always follow the pattern stores/store_hash. This is the store that created the webhook.
scope The event registered when the webhook was created.
data A lightweight description of the event that triggered the webhook. Will vary depending on the event registered.
hash The payload data json encoded then passed through sh1 encryption.

Request and Response

Never worked with webhooks before? Check out the tutorial on creating webhooks.

All webhooks requests must include the following in their HTTP headers:

     Accept: application/json
     Content-Type: application/json
     X-Auth-Client: <the OAuth client id>
     X-Auth-Token: <the OAuth token>
/POST Webhook
Request: https://api.bigcommerce.com/stores/{{store_hash}}/v2/hooks
curl -X POST \
  https://api.bigcommerce.com/stores/store_hash/v2/hooks \
  -H 'Accept: application/json' \
  -H 'X-Auth-Client: your-client-id \
  -H 'X-Auth-Token: your-auth-token \
  -d '{
  "scope": "store/cart/lineItem/*",
  "destination": "https://myapp.herokuapp.com/",
  "is_active": true
Response 201 Created
/POST Webhook
{
  "id": 14270456,
  "client_id": "your-client-id",
  "store_hash": "your_store_hash",
  "scope": "store/cart/lineItem/*",
  "destination": "https://779aca97.ngrok.io/webhooks",
  "headers": null,
  "is_active": true,
  "created_at": 1531326542,
  "updated_at": 1531337178
}
Name Description Type
id A read-only value that uniquely identifies a webhook object. Do not attempt to set this value in a PUT or POST. integer
client_id The OAuth client ID that uniquely identifies your application. BigCommerce returns this name-value pair in the JSON body of its responses. string
store_hash The hash value that uniquely identifies the store. Your application does not need to set this value via the JSON object; instead, you pass it in the path of your API requests. string
scope Value is the event you would like to listen for. See List of Webhook Events for the full list of possibilities. Wild Cards are supported for scope. (Required) string
destination value is the callback’s fully qualified URI. This should be an endpoint configured on your app server to receive webhook payloads. (Required) string
headers The headers object contains one or more name-value pairs, both string values. If you choose to include a headers object, BigCommerce will include the name-value pair(s) in the HTTP header of its POST requests to your callback URI at runtime. While this feature could be used for any purpose, one is to use it to set a secret authorization key and check it at runtime. This provides an additional level of assurance that the POST request came from BigCommerce instead of some other party, such as a malicious actor. (Optional) string
is_active Value specifies whether a webhook is active or inactive. By default, new webhooks will be set to be inactive and will have a blank value. If you want to create a webhook that should be active initially, you can pass the following name-value pair: “is_active”: true. (Optional) boolean
created_at The time at which the webhook was created. date-time Unix Epoch
updated_at The time at which the webhook was last updated. date-time Unix Epock

An HTTP 201 response indicates that the webhook was set successfully.

One-Minute Timeout

Following the creation of a webhook, it can take up to one minute for BigCommerce to start sending POST requests to your callback URI.

/GET All Webhooks
Request: https://api.bigcommerce.com/stores/{{store_hash}}/v2/hooks
//Response 200 OK

[
    {
        "id": 14270466,
        "client_id": "your-client-id",
        "store_hash": "your_store_hash",
        "scope": "store/product/created",
        "destination": "https://779aca97.ngrok.io/webhooks",
        "headers": null,
        "is_active": true,
        "created_at": 1531326542,
        "updated_at": 1531337178
    },
    {
        "id": 14270713,
        "client_id": "your-client-id",
        "store_hash": "your_store_hash",
        "scope": "store/product/updated",
        "destination": "https://779aca97.ngrok.io/webhooks",
        "headers": null,
        "is_active": false,
        "created_at": 1531338589,
        "updated_at": 1531338589
    }
]
/GET a Single Webhook
To get a single webhook use the `id`. Request: https://api.bigcommerce.com/stores/{{store_hash}}/v2/hooks/id
{
  "id": 14270466,
  "client_id": "your-client-id",
  "store_hash": "your_store_hash",
  "scope": "store/product/created",
  "destination": "https://779aca97.ngrok.io/webhooks",
  "headers": null,
  "is_active": false,
  "created_at": 1531326542,
  "updated_at": 1531337178
}
/PUT Webhook
Update a webhook using the id. Once the webhook is created all the fields below can be changed via an update request. Request: https://api.bigcommerce.com/stores/{{store_hash}}/v2/hooks/id
{
 "scope": "store/product/updated",
 "destination": "https://779aca97.ngrok.io/webhooks",
 "is_active": false
}


//Response 200 OK

{
    "id": 14270466,
    "client_id": "ejoftto9hv8xlip01cckcg53v7g3lrl",
    "store_hash": "jrah6gmn",
    "scope": "store/product/created",
    "destination": "https://779aca97.ngrok.io/webhooks",
    "headers": null,
    "is_active": false,
    "created_at": 1531326542,
    "updated_at": 1531337178
}
/DELETE a Wehbook
Request: https://api.bigcommerce.com/stores/{{store_hash}}/v2/hooks/id
//Response 200 OK
{
    "id": 14270466,
    "client_id": "ejoftto9hv8xlip01cckcg53v7g3lrl",
    "store_hash": "jrah6gmn",
    "scope": "store/product/created",
    "destination": "https://779aca97.ngrok.io/webhooks",
    "headers": null,
    "is_active": false,
    "created_at": 1531326542,
    "updated_at": 1531337178
}

There is not a way to delete all webhooks on a store. Run a GET request for the webhook id, then send a request to the delete URI to remove each one. It returns a 200 OK for the response with the deleted hook. When requesting a list of hook, the hook id is not available.

If webhooks are no longer being used, either delete them or set is_active:false.


Receiving the Callback

You’ll need to build an application and configure your server to receive the callback we send when events are triggered.

Need to set up a quick destination URL for testing? See Tools for Debugging and Testing Webhooks.


Respond to Webhook Callbacks

You’ll need to build an application and configure your server to receive the callback we send when events are triggered.

To acknowledge that you received the webhook without issue, your server should return a 200 HTTP status code. Any other information you return in the request headers or request body will be ignored. Any response code outside the 200 range, including 3_xx_ codes, will indicate to us that you did not receive the webhook. When a webhook is not received (for whatever reason), we will retry the callback as described below.

Need to set up a quick destination URL for testing? See Tools for testing webhooks.


Callback Retry Mechanism

The webhooks service will do its best to deliver events to your callback URI. If your server indicates that the webhook payload has not been received, the dispatch service will take the following actions: If an app server responds to a webhook payload with anything other than a 2_xx_ response, or times out, the app will be blocked for 60 seconds. Webhooks created during that 60-second block will be queued up to send on the next scheduled retry attempt after the block expires, so that webhooks are not lost.

The webhook dispatcher will then attempt several retries (at increasing intervals) until the maximum retry limit is reached.

Retry Intervals

  • 60 seconds after the most recent failure
  • 180 seconds after the most recent failure
  • 180 seconds after the most recent failure
  • 300 seconds after the most recent failure
  • 600 seconds after the most recent failure
  • 900 seconds after the most recent failure
  • 1800 seconds after the most recent failure
  • 3600 seconds after the most recent failure
  • 7200 seconds after the most recent failure
  • 21600 seconds after the most recent failure
  • 50400 seconds after the most recent failure
  • 86400 seconds (24 hours) after the most recent failure

After the final retry attempt (cumulatively, 48 hours after the first delivery attempt), the webhook will automatically be deactivated, and we will send an email to the developer’s email address registered on the subscribing app. You can reactivate the webhook by setting the is_active flag back to true via a /PUT request to the hooks resource.


Webhook Security

To ensure that webhook payloads are secure against activity by a malicious actor, we take a three-pronged approach:

  • Webhook payloads contain minimal information about the store and event, for example the ID identifying the order or cart. To access potentially sensitive information on a store, a malicious actor would need to be fully authenticated against that store’s API in order to request full details.
  • Webhook payloads are sent over a TLS-encrypted connection.
  • For added security, you can include custom headers in your webhook creation request, and these headers will be sent in the payload when an event you subscribe to occurs. If your app endpoint is secured by basic authentication, you could set your own basic auth headers to authenticate the payload at runtime.

Troubleshooting

Why am I not receiving event payloads to my callback URI?

If your app does not return an HTTP 2_xx_ to BigCommerce after receiving the webhook event payload, BigCommerce considers it a failure. BigCommerce will keep trying for a little over 48 hours. At the end of that time, BigCommerce sends an email to the email address set during app registration and disables the webhook by setting the is_active flag to false.

You can proactively check to make sure that everything is OK by periodically making a GET request and checking the is_active flag.

If you receive an email or discover that the is_active flag has been flipped to false, try the following:

Check to see if your app is responding to the event payload with something other than HTTP 200. Check to make sure that your server has a valid TLS/SSL setup. One way to do this is by visiting the following website: https://sslcheck.globalsign.com. Any of the following will cause the TLS/SSL handshake to fail: Self-signed certificate. Host name of the certificate does not match the server’s DNS. Your server’s key or trust store has not been loaded up with the intermediate certificates necessary to establish the chain of trust. Once you have resolved the issue preventing the connection, send a PUT request to flip the is_active flag back to true. This will cause BigCommerce to start sending the event payloads to your callback URI again.

Why am I not receiving a 201 response after creating a webhook?

After sending a POST request to create a webhook, you should get an HTTP 201 back. If you do not, check your TLS/SSL setup and be sure that your request contains the following headers:

     Accept: application/json
     Content-Type: application/json
     X-Auth-Client: <the OAuth client id>
     X-Auth-Token: <the OAuth token>

Tools for Debugging and Testing Webhooks

ngrok
As you are building your integration, you might want to test webhooks on your local dev machines.

We suggest using ngrok, which you can use to easily set up tunnels between a server running on localhost and a public URL. This will enable you to send our webhooks to your localhost environments via a public URL. No production push is required.

Need help on ngrok and webhooks see our tutorial.

Webhook Tester
This allows for webhooks to be quickly tested or checked.