Difference between revisions of "API Webhook"

From Spiffy Stores Knowledge Base

m
 
(21 intermediate revisions by the same user not shown)
Line 1: Line 1:
 
Webhooks are a useful tool for apps that want to execute code after a specific event happens on a store, for example, after a customer creates a cart on the storefront, or a merchant creates a new product in their admin.
 
Webhooks are a useful tool for apps that want to execute code after a specific event happens on a store, for example, after a customer creates a cart on the storefront, or a merchant creates a new product in their admin.
  
Instead of telling your app to make an API call every X number of minutes to check if a specific event has occurred on a shop, you can register webhooks, which send an HTTP request from the store telling your app that the event has occurred. This uses far less API requests overall, allowing you to build more robust apps, and update your app instantly after a webhook is received.
+
Instead of telling your app to make an API call every X number of minutes to check if a specific event has occurred on a store, you can register webhooks, which send an HTTP request from the store telling your app that the event has occurred. This uses far less API requests overall, allowing you to build more robust apps, and update your app instantly after a webhook is received.
  
 
Webhooks are scoped to the app they're registered to. This means that when a webhook is registered to an app, other apps can't view, modify, or delete it.
 
Webhooks are scoped to the app they're registered to. This means that when a webhook is registered to an app, other apps can't view, modify, or delete it.
  
==Anatomy of a Webhook==
+
If you're not a developer, or you don't have access to any developer skills, don't despair! You might want to look at a service such as [https://zapier.com/ Zapier] which offers a quick and simple way for you to connect your Spiffy Store to hundreds of other web applications and services.
<br>
+
 
When an event occurs in a shop that corresponds to a registered webhook, Spiffy Stores sends a webhook notification to the specified URL. The webhook contains a payload formatted as JSON, as well applicable HTTP headers. For example, the following headers are sent as part of the <pre>orders/create</pre> webhook.
+
API Webhooks should not be confused with our older, limited Notification Webhooks. The Notification Webhooks are designed to only provide a simple order notification service, whereas API Webhooks can be registered on a much wider range of events.
 +
 
 +
== Using Webhooks ==
 +
 
 +
A Webhook allows you to register an ''http://'' or ''https://'' URL with the associated event data being stored in either JSON or XML formats.
 +
 
 +
Webhooks are most commonly triggered when
 +
 
 +
* An order is placed and you want to notify your shipping agents
 +
* A product's price is changed
 +
* A new product is created in order to update social media platforms
 +
* An order is paid so that your accounting software can be updated
 +
 
 +
== Webhook events ==
 +
 
 +
You can register a webhook for the following events
 +
 
 +
; Customers : creation/deletion/disable/update
 +
; Orders : creation/payment
 +
 
 +
Further Webhook events will be added in the near future.
 +
 
 +
== Managing Webhooks ==
 +
 
 +
<gallery heights="200px" widths="200px" class="right">
 +
File:webhooks1.jpg|Managing Webhooks
 +
</gallery>
 +
 
 +
Webhooks can be created and managed on the 'Accounts -> API Webhooks' page.
 +
 
 +
You can create, edit and delete Webhooks on this page. Any Webhooks created using this interface are listed as having a ''Manual'' source.
 +
 
 +
When you create a Webhook, you need to specify which event you are trying to register the webhook for, the format of the event data being either JSON or XML and finally the callback URL which needs to be posted when the event occurs.
  
* '''X-Spiffy-Topic''': orders/create
+
Webhooks can also be created through the API, and these will be listed in the interface, but you cannot edit or delete them. They can only be managed through the API interface. In some cases, applications can supply a name for the webhook, so that you can easily identify the source of the webhook registration.
* '''X-Spiffy-Hmac-Sha256''': XWmrwMey6OsLMeiZKwP4FppHH3cmAiiJJAweH5Jo4bM=
 
* '''X-Spiffy-Shop-Domain''': johns-apparel.spiffystores.com
 
  
etc.
+
== Anatomy of a Webhook ==
  
Some of the returned HTTP headers can be useful for your app. For example, X-Spiffy-Hmac-Sha256 is used to authenticate webhooks, and  X-Spiffy-Shop-Domain is useful for determining the store context. See the webhooks tutorial for more information concerning authenticating webhooks, and the OAuth docs for general information concerning authentication.
+
When an event occurs in a store that corresponds to a registered webhook, Spiffy Stores sends a webhook notification to the specified URL. The webhook contains a payload formatted as JSON, as well applicable HTTP headers. For example, the following headers are sent as part of the ''orders/create'' webhook.
  
==List of Supported Webhook Topics==
+
<pre>
 +
X-Spiffy-Stores-ID: 0c1c9920-5c9c-012d-bd34-000c295ec56b
 +
X-Spiffy-Stores-Topic: orders/create
 +
X-Spiffy-HMAC-SHA256: XWmrwMey6OsLMeiZKwP4FppHH3cmAiiJJAweH5Jo4bM=
 +
X-Spiffy-Stores-Shop-Domain: mynewstore.spiffystores.com
 +
X-Spiffy-Stores-Order-Id: 12345
 +
...
 +
</pre>
 +
 
 +
Some of the returned HTTP headers can be useful for your app. For example, ''X-Spiffy-Stores-HMAC-SHA256'' is used to authenticate webhooks, and ''X-Spiffy-Stores-Shop-Domain'' is useful for determining the store context.
 +
 
 +
== List of Supported Webhook Topics ==
  
 
Event data can be stored as JSON or XML. Webhooks can be registered for the following events:
 
Event data can be stored as JSON or XML. Webhooks can be registered for the following events:
Line 1,270: Line 1,311:
 
<br>
 
<br>
  
==Webhook properties==
+
== Webhook properties ==
  
 
{| class="reference"
 
{| class="reference"
|address
+
!id
|<pre>"address": "http://apple.com/uninstall"</pre><br>The URI where the webhook should send the POST request when the event occurs.
+
|<pre>{ "id": 901431826 }</pre>
 +
The unique numeric identifier for the webhook.
 
|-
 
|-
|created_at
+
!address
|<pre>"created_at": "2012-09-28T11:50:07-04:00"</pre><br/>The date and time when the webhook was created. The API returns this value in ISO 8601 format.
+
|<pre>{ "address": "https://apple.com/uninstall" }</pre>
 +
The URI where the webhook should send the POST request when the event occurs.
 
|-
 
|-
|fields
+
!format
|<pre>"fields": ["id","updated_at"]</pre><br/>(Optional) An array of fields which should be included in webhooks.
+
|<pre>{ "format": "json" }</pre>
 +
The format in which the webhook should send the data. Valid values are ''json'' and ''xml''.
 
|-
 
|-
|format
+
!topic
|<pre>"format": "json"</pre><br/>The format in which the webhook should send the data. Valid values are json and xml.
+
|<pre>{ "topic": "app/uninstalled" }</pre>
|-
+
The event that will trigger the webhook. Valid values are:  
|id
 
|<pre>"id": 901431826</pre><br/>The unique numeric identifier for the webhook.
 
|-
 
|metafield_namespaces
 
|<pre>"metafield_namespaces": ["google","inventory"]</pre><br/>(Optional) An array of namespaces for metafields that should be included in webhooks.
 
|-
 
|topic
 
|<pre>"topic": "app/uninstalled"</pre><br/>The event that will trigger the webhook. Valid values are:  
 
  
 
* app/uninstalled
 
* app/uninstalled
Line 1,342: Line 1,378:
 
* themes/update
 
* themes/update
 
|-
 
|-
|updated_at
+
!source
|<pre>"updated_at": "2012-09-28T11:50:07-04:00"</pre><br/>The date and time when the webhook was updated. The API returns this value in ISO 8601 format.
+
|<pre>{ "source": "api" }</pre>
 +
The source which created the webhook. Valid values are ''api'' and ''manual''.
 +
|-
 +
!created_at
 +
|<pre>{ "created_at": "2012-09-28T11:50:07-04:00" }</pre>
 +
The date and time when the webhook was created. The API returns this value in ISO 8601 format.
 +
|-
 +
!updated_at
 +
|<pre>{ "updated_at": "2012-09-28T11:50:07-04:00" }</pre>
 +
The date and time when the webhook was updated. The API returns this value in ISO 8601 format.
 
|}
 
|}
  
 
== Endpoints ==
 
== Endpoints ==
<br>
 
  
===GET /admin/webhooks.json===
+
=== <code>GET /api/webhooks.json</code> ===
 +
 
 +
Get a list of webhooks.
 +
 
 +
==== Optional Parameters ====
 +
 
 
{| class="reference"
 
{| class="reference"
|address
+
!limit
|Use this parameter to retrieve only webhooks that possess the URI where the webhook sends the POST request when the event occurs.
+
|Number of results returned. The default is 30, with a maximum of 50 in a single request.
 +
|-
 +
!page
 +
|The number of the page to return. The number of results per page is set by the <code>limit</code> parameter. If more results are required, then submit the request again, increasing the page number each time.
 
|-
 
|-
|created_at_max
+
!since_id
|Use this parameter to retrieve only webhooks that were created before a given date and time (format: 2014-04-25T16:15:47-04:00).
+
|Limit the results to only include objects which have an id greater than the given value.
 
|-
 
|-
|created_at_min
+
!address
|Use this parameter to retrieve only webhooks that were created after a given date and time (format: 2014-04-25T16:15:47-04:00).
+
|Limit the results to only include webhooks with the given address (URI).
 
|-
 
|-
|fields
+
!topic
|A comma-separated list of the properties you want returned for each item in the result list. Use this parameter to restrict the returned list of items to showing only those properties you specify.
+
|Limit the results to only include webhooks with the given topic.
 
|-
 
|-
|limit
+
!source
|The maximum number of webhooks that should be returned. Setting this parameter outside the maximum range will result in an error.
+
|Limit the results to only include webhooks with the given source.
(default: 50) (maximum: 250)
 
 
|-
 
|-
|page
+
!created_at_min
|The page number of the result list to retrieve. Use this in tandem with limit to page through the webhooks in a shop.
+
|Return only the webhooks created after the given date and time. Use the format "2014-12-31 12:00".
(default: 1)
 
 
|-
 
|-
|since_id
+
!created_at_max
|Use this parameter to restrict the returned list to only webhooks whose id is greater than the specified id.
+
|Return only the webhooks created before the given date and time. Use the format "2014-12-31 12:00".
 
|-
 
|-
|topic
+
!updated_at_min
|Show webhooks with a given topic. Valid topics are:
+
|Return only the webhooks updated after the given date and time. Use the format "2014-12-31 12:00".
 +
|-
 +
!updated_at_max
 +
|Return only the webhooks updated before the given date and time. Use the format "2014-12-31 12:00".
 +
|-
 +
!fields
 +
|A comma-separated list of fields to return in the response.
 +
|}
  
* app/uninstalled
+
==== Example Request and Response ====
* carts/create
+
 
* carts/update
+
<pre>
* checkouts/create
+
GET /api/webhooks.json
* checkouts/delete
+
 
* checkouts/update
+
HTTP/1.1 200 OK
* collection_listings/add
+
{
* collection_listings/remove
+
  "webhooks": [
* collection_listings/update
+
    {
* collections/create
+
      "id": 4759306,
* collections/delete
+
      "address": "https:\/\/apple.com",
* collections/update
+
      "topic": "orders\/create",
* customer_groups/create
+
      "created_at": "2017-03-20T16:02:17-04:00",
* customer_groups/delete
+
      "updated_at": "2017-03-20T16:02:17-04:00",
* customer_groups/update
+
      "format": "json"
* customers/create
+
    },
* customers/delete
+
    ...
* customers/disable
+
  ]
* customers/enable
+
}
* customers/update
+
 
* draft_orders/create
+
Examples using filters
* draft_orders/delete
+
 
* draft_orders/update
+
GET /api/webhooks.json?fields=id,address
* fulfillment_events/create
+
 
* fulfillment_events/delete
+
GET /api/webhooks.json?since_id=4759306
* fulfillments/create
+
</pre>
* fulfillments/update
+
 
* order_transactions/create
+
=== <code>GET /api/webhooks/count.json</code> ===
* orders/cancelled
+
 
* orders/create
+
Return a count of the number of webhooks.
* orders/delete
+
 
* orders/fulfilled
+
==== Optional Parameters ====
* orders/paid
+
 
* orders/partially_fulfilled
+
{| class="reference"
* orders/updated
+
!since_id
* product_listings/add
+
|Limit the results to only include objects which have an id greater than the given value.
* product_listings/remove
+
|-
* product_listings/update
+
!address
* products/create
+
|Limit the results to only include webhooks with the given address (URI).
* products/delete
 
* products/update
 
* refunds/create
 
* shop/update
 
* themes/create
 
* themes/delete
 
* themes/publish
 
* themes/update
 
 
|-
 
|-
| updated_at_min
+
!topic
|Use this parameter to retrieve only webhooks that were updated before a given date and time (format: 2014-04-25T16:15:47-04:00).
+
|Limit the results to only include webhooks with the given topic.
 
|-
 
|-
| updated_at_max
+
!source
|Use this parameter to retrieve only webhooks that were updated after a given date and time (format: 2014-04-25T16:15:47-04:00).
+
|Limit the results to only include webhooks with the given source.
|}
+
|-
 +
!created_at_min
 +
|Return only the webhooks created after the given date and time. Use the format "2014-12-31 12:00".
 +
|-
 +
!created_at_max
 +
|Return only the webhooks created before the given date and time. Use the format "2014-12-31 12:00".
 +
|-
 +
!updated_at_min
 +
|Return only the webhooks updated after the given date and time. Use the format "2014-12-31 12:00".
 +
|-
 +
!updated_at_max
 +
|Return only the webhooks updated before the given date and time. Use the format "2014-12-31 12:00".
 +
|}
 +
 
 +
==== Example Request and Response ====
 +
 
 +
<pre>
 +
GET /api/webhooks/count.json
 +
 
 +
HTTP/1.1 200 OK
 +
 
 +
{
 +
  "count": 15
 +
}
 +
 
 +
Examples using filters
 +
 
 +
GET /api/webhooks/count.json?topic=orders/create
 +
</pre>
  
<br>
+
=== <code>GET /api/webhooks/WEBHOOK_ID.json</code> ===
 +
 
 +
Retrieves a single webhook by ID.
  
====Get a list of all webhooks for your shop.====
+
==== Optional Parameters ====
  
<code>GET /admin/webhooks.json</code>
+
{| class="reference"
 +
!fields
 +
|A comma-separated list of fields to return in the response.
 +
|}
 +
 
 +
==== Example Request and Response ====
  
 
<pre>
 
<pre>
 +
GET /api/webhooks/248.json
 +
 
HTTP/1.1 200 OK
 
HTTP/1.1 200 OK
 +
 
{
 
{
   "webhooks": [
+
   "webhook": {
     {
+
     "id": 248,
      "id": 4759306,
+
    "address": "https://mytestapps.com.au/webhooks/app_uninstalled",
      "address": "http:\/\/apple.com",
+
    "created_at": "2016-10-13T16:16:52.210+11:00",
      "topic": "orders\/create",
+
    "updated_at": "2016-10-13T16:16:52.210+11:00",
      "created_at": "2017-03-20T16:02:17-04:00",
+
    "format": "json",
      "updated_at": "2017-03-20T16:02:17-04:00",
+
     "topic": "app/uninstalled"
      "format": "json",
+
  }
      "fields": [
 
      ],
 
      "metafield_namespaces": [
 
      ]
 
    },
 
     {
 
      "id": 901431826,
 
      "address": "http:\/\/apple.com\/uninstall",
 
      "topic": "app\/uninstalled",
 
      "created_at": "2017-03-20T16:02:17-04:00",
 
      "updated_at": "2017-03-20T16:02:17-04:00",
 
      "format": "json",
 
      "fields": [
 
      ],
 
      "metafield_namespaces": [
 
      ]
 
    }
 
  ]
 
 
}
 
}
 
</pre>
 
</pre>
<br>
 
====Get a list of all webhooks for your shop after a specified ID====
 
  
<code>GET /admin/webhooks.json?since_id=4759306</code>
+
=== <code>POST /api/webhooks.json</code> ===
 +
 
 +
Create a webhook subscription by specifying both an address and a topic. This API call can be used by apps to install any notifications that the app needs.
 +
 
 +
==== Example Request and Response ====
  
 
<pre>
 
<pre>
HTTP/1.1 200 OK
+
POST /api/webhooks.json
 +
 
 
{
 
{
   "webhooks": [
+
   "webhook": {
     {
+
     "topic": "orders/create",
      "id": 901431826,
+
    "address": "https://whatever.hostname.com/",
      "address": "http:\/\/apple.com\/uninstall",
+
    "format": "json"
      "topic": "app\/uninstalled",
+
  }
      "created_at": "2017-03-20T16:02:17-04:00",
 
      "updated_at": "2017-03-20T16:02:17-04:00",
 
      "format": "json",
 
      "fields": [
 
      ],
 
      "metafield_namespaces": [
 
      ]
 
    }
 
  ]
 
 
}
 
}
</pre>
 
  
<br>
+
HTTP/1.1 201 Created
 
 
===GET /admin/webhooks/count.json===
 
<br>
 
{| class="wikitable" style="width: 100%"
 
|style="width: 30%"| address
 
|Use this parameter to retrieve only webhooks that possess the URI where the webhook sends the POST request when the event occurs.
 
|-
 
| topic
 
|Show webhooks with a given topic. Valid topics are: app/uninstalled, carts/create, carts/update, checkouts/create, checkouts/delete, checkouts/update, collection_listings/add, collection_listings/remove, collection_listings/update, collections/create, collections/delete, collections/update, customer_groups/create, customer_groups/delete, customer_groups/update, customers/create, customers/delete, customers/disable, customers/enable, customers/update, draft_orders/create, draft_orders/delete, draft_orders/update, fulfillment_events/create, fulfillment_events/delete, fulfillments/create, fulfillments/update, order_transactions/create, orders/cancelled, orders/create, orders/delete, orders/fulfilled, orders/paid, orders/partially_fulfilled, orders/updated, product_listings/add, product_listings/remove, product_listings/update, products/create, products/delete, products/update, refunds/create, shop/update, themes/create, themes/delete, themes/publish, themes/update
 
|}
 
 
 
<br>
 
 
 
====Count all of the webhooks for topic 'orders/create'====
 
  
<code>GET /admin/webhooks/count.json?topic=orders/create</code>
 
 
<pre>
 
HTTP/1.1 200 OK
 
 
{
 
{
   "count": 3
+
   "webhook": {
 +
    "id": 1047897619,
 +
    "address": "http://whatever.hostname.com/",
 +
    "topic": "orders/create",
 +
    "created_at": "2017-03-20T16:02:33-04:00",
 +
    "updated_at": "2017-03-20T16:02:33-04:00",
 +
    "format": "json"
 +
  }
 
}
 
}
 
</pre>
 
</pre>
  
====Count all of the webhooks for your shop.====
+
=== <code>PUT /api/webhooks/WEBHOOK_ID.json</code> ===
  
<code>GET /admin/webhooks/count.json</code>
+
Update a webhook subscription's topic or address URIs.
 +
 
 +
==== Example Request and Response ====
  
 
<pre>
 
<pre>
HTTP/1.1 200 OK
+
PUT /api/webhooks/4759306.json
 +
 
 
{
 
{
   "count": 25
+
   "webhook": {
 +
    "id": 4759306,
 +
    "address": "https://somewhere-else.com/"
 +
  }
 
}
 
}
</pre>
 
  
===GET /admin/webhooks/4759306.json===
+
HTTP/1.1 200 OK
 
 
Get a single webhook
 
 
 
{| class="wikitable" style="width: 100%"
 
|style="width: 30%"|fields
 
|A comma-separated list of the properties you want returned for each item in the result list. Use this parameter to restrict the returned list of items to showing only those properties you specify.
 
|}
 
 
 
 
 
====Get a single webhook by its id.====
 
 
 
<code>GET /admin/webhooks/#{id}.json</code>
 
  
<pre>
 
HTTP/1.1 200 OK
 
 
{
 
{
 
   "webhook": {
 
   "webhook": {
 
     "id": 4759306,
 
     "id": 4759306,
     "address": "http:\/\/apple.com",
+
     "address": "http://somewhere-else.com/",
     "topic": "orders\/create",
+
     "topic": "orders/create",
 
     "created_at": "2017-03-20T16:02:17-04:00",
 
     "created_at": "2017-03-20T16:02:17-04:00",
     "updated_at": "2017-03-20T16:02:17-04:00",
+
     "updated_at": "2017-03-20T16:04:29-04:00",
     "format": "json",
+
     "format": "json"
    "fields": [
 
    ],
 
    "metafield_namespaces": [
 
    ]
 
 
   }
 
   }
 
}
 
}
 
</pre>
 
</pre>
  
 +
=== <code>DELETE /api/webhooks/WEBHOOK_ID.json</code> ===
  
===POST /admin/webhooks.json===
+
Delete a webhook.
  
Every webhook needs a topic and an address. Failure to have a topic or an address will result in a 422 - Unprocessable Entity error.
+
==== Example Request and Response ====
format
 
  
{| class="wikitable" style="width: 100%"
+
<pre>
|style="width: 30%"|format
+
DELETE /api/webhooks/234548.json
|Use this parameter to select the format to receive the data in. Valid values are json and xml.
 
(default: json)
 
|}
 
  
 +
HTTP/1.1 200 OK
  
After installing a Spiffy Stores App, it’s a pain for store owners to have to manually install webhooks the app needs. Automate that by using this API call.
+
{}
 
 
<code>POST /admin/webhooks.json</code>
 
 
 
<pre>
 
{
 
  "webhook": {
 
    "topic": "orders\/create",
 
    "address": "http:\/\/whatever.hostname.com\/",
 
    "format": "json"
 
  }
 
}
 
</pre>
 
 
 
====Response====
 
 
 
<pre>
 
HTTP/1.1 201 Created
 
{
 
  "webhook": {
 
    "id": 1047897619,
 
    "address": "http:\/\/whatever.hostname.com\/",
 
    "topic": "orders\/create",
 
    "created_at": "2017-03-20T16:02:33-04:00",
 
    "updated_at": "2017-03-20T16:02:33-04:00",
 
    "format": "json",
 
    "fields": [
 
    ],
 
    "metafield_namespaces": [
 
    ]
 
  }
 
}
 
</pre>
 
 
 
Trying to create a webhook without an address or topic will return an error
 
 
 
<code>POST /admin/webhooks.json</code>
 
 
 
<pre>
 
{
 
  "webhook": {
 
    "body": "foobar"
 
  }
 
}
 
</pre>
 
 
 
===== Response=====
 
<pre>
 
HTTP/1.1 422 Unprocessable Entity
 
{
 
  "errors": {
 
    "topic": [
 
      "can't be blank",
 
      "Invalid topic specified. Topics allowed: app\/uninstalled, carts\/create, carts\/update, catalogs\/create, catalogs\/delete, channels\/delete, checkouts\/create, checkouts\/delete, checkouts\/update, collection_listings\/add, collection_listings\/remove, collection_listings\/update, collection_publications\/create, collection_publications\/delete, collection_publications\/update, collections\/create, collections\/delete, collections\/update, customer_groups\/create, customer_groups\/delete, customer_groups\/update, customers\/create, customers\/delete, customers\/disable, customers\/enable, customers\/update, disputes\/create, disputes\/update, draft_orders\/create, draft_orders\/delete, draft_orders\/update, fulfillment_events\/create, fulfillment_events\/delete, fulfillments\/create, fulfillments\/update, order_transactions\/create, orders\/cancelled, orders\/create, orders\/delete, orders\/fulfilled, orders\/paid, orders\/partially_fulfilled, orders\/updated, product_listings\/add, product_listings\/remove, product_listings\/update, product_publications\/create, product_publications\/delete, product_publications\/update, products\/create, products\/delete, products\/update, refunds\/create, shop\/update, tax_services\/create, tax_services\/update, themes\/create, themes\/delete, themes\/publish, themes\/update, variants\/in_stock, variants\/out_of_stock"
 
    ],
 
    "address": [
 
      "can't be blank"
 
    ]
 
  }
 
}
 
</pre>
 
 
 
===PUT /admin/webhooks/4759306.json===
 
 
 
Update a webhook's topic and/or address URIs.
 
 
 
Change a webhook so that it POSTs to a different address:
 
 
 
<code>PUT /admin/webhooks/#{id}.json</code>
 
 
 
<pre>
 
{
 
  "webhook": {
 
    "id": 4759306,
 
    "address": "http:\/\/somewhere-else.com\/"
 
  }
 
}
 
</pre>
 
=====Response=====
 
 
 
<pre>
 
HTTP/1.1 200 OK
 
{
 
  "webhook": {
 
    "id": 4759306,
 
    "address": "http:\/\/somewhere-else.com\/",
 
    "topic": "orders\/create",
 
    "created_at": "2017-03-20T16:02:17-04:00",
 
    "updated_at": "2017-03-20T16:04:29-04:00",
 
    "format": "json",
 
    "fields": [
 
    ],
 
    "metafield_namespaces": [
 
    ]
 
  }
 
}
 
 
</pre>
 
</pre>
  
===DELETE /admin/webhooks/4759306.json===
 
 
Delete a webhook
 
 
Remove an existing webhook from a store
 
 
<code>DELETE /admin/webhooks/#{id}.json</code>
 
 
===== Response=====
 
 
<pre>
 
HTTP/1.1 200 OK
 
{}
 
</pre>
 
 
== Further Reference ==
 
== Further Reference ==
  

Latest revision as of 14:30, 6 June 2018

Webhooks are a useful tool for apps that want to execute code after a specific event happens on a store, for example, after a customer creates a cart on the storefront, or a merchant creates a new product in their admin.

Instead of telling your app to make an API call every X number of minutes to check if a specific event has occurred on a store, you can register webhooks, which send an HTTP request from the store telling your app that the event has occurred. This uses far less API requests overall, allowing you to build more robust apps, and update your app instantly after a webhook is received.

Webhooks are scoped to the app they're registered to. This means that when a webhook is registered to an app, other apps can't view, modify, or delete it.

If you're not a developer, or you don't have access to any developer skills, don't despair! You might want to look at a service such as Zapier which offers a quick and simple way for you to connect your Spiffy Store to hundreds of other web applications and services.

API Webhooks should not be confused with our older, limited Notification Webhooks. The Notification Webhooks are designed to only provide a simple order notification service, whereas API Webhooks can be registered on a much wider range of events.

Using Webhooks

A Webhook allows you to register an http:// or https:// URL with the associated event data being stored in either JSON or XML formats.

Webhooks are most commonly triggered when

  • An order is placed and you want to notify your shipping agents
  • A product's price is changed
  • A new product is created in order to update social media platforms
  • An order is paid so that your accounting software can be updated

Webhook events

You can register a webhook for the following events

Customers 
creation/deletion/disable/update
Orders 
creation/payment

Further Webhook events will be added in the near future.

Managing Webhooks

Webhooks can be created and managed on the 'Accounts -> API Webhooks' page.

You can create, edit and delete Webhooks on this page. Any Webhooks created using this interface are listed as having a Manual source.

When you create a Webhook, you need to specify which event you are trying to register the webhook for, the format of the event data being either JSON or XML and finally the callback URL which needs to be posted when the event occurs.

Webhooks can also be created through the API, and these will be listed in the interface, but you cannot edit or delete them. They can only be managed through the API interface. In some cases, applications can supply a name for the webhook, so that you can easily identify the source of the webhook registration.

Anatomy of a Webhook

When an event occurs in a store that corresponds to a registered webhook, Spiffy Stores sends a webhook notification to the specified URL. The webhook contains a payload formatted as JSON, as well applicable HTTP headers. For example, the following headers are sent as part of the orders/create webhook.

X-Spiffy-Stores-ID: 0c1c9920-5c9c-012d-bd34-000c295ec56b
X-Spiffy-Stores-Topic: orders/create
X-Spiffy-HMAC-SHA256: XWmrwMey6OsLMeiZKwP4FppHH3cmAiiJJAweH5Jo4bM=
X-Spiffy-Stores-Shop-Domain: mynewstore.spiffystores.com
X-Spiffy-Stores-Order-Id: 12345
...

Some of the returned HTTP headers can be useful for your app. For example, X-Spiffy-Stores-HMAC-SHA256 is used to authenticate webhooks, and X-Spiffy-Stores-Shop-Domain is useful for determining the store context.

List of Supported Webhook Topics

Event data can be stored as JSON or XML. Webhooks can be registered for the following events:

Events Topics
Cart
carts/create, carts/update

{
  "id": "eeafa272cebfd4b22385bc4b645e762c",
  "token": "eeafa272cebfd4b22385bc4b645e762c",
  "line_items": [
    {
      "id": 1234567,
      "properties": {
      },
      "quantity": 3,
      "variant_id": 1234567,
      "key": "1234567:f816dcc3b2e26822a28626a786eac953",
      "title": "Example T-Shirt - ",
      "price": "19.99",
      "original_price": "19.99",
      "discounted_price": "19.99",
      "line_price": "59.97",
      "original_line_price": "59.97",
      "total_discount": "0.00",
      "discounts": [
      ],
      "sku": "example-shirt-s",
      "grams": 200,
      "vendor": "Acme",
      "product_id": 327475578523353102,
      "gift_card": false
    }
  ]
}
Checkout
checkouts/create, checkouts/delete, checkouts/update

{
  "id": 327474488104976385,
  "token": "123123123",
  "cart_token": "eeafa272cebfd4b22385bc4b645e762c",
  "email": "example@email.com",
  "gateway": null,
  "buyer_accepts_marketing": false,
  "created_at": "2017-03-20T16:02:28-04:00",
  "updated_at": "2017-03-20T16:02:28-04:00",
  "landing_site": null,
  "note": null,
  "note_attributes": [
  ],
  "referring_site": null,
  "shipping_lines": [
  ],
  "subtotal_price": "398.00",
  "taxes_included": false,
  "total_discounts": "0.00",
  "total_line_items_price": "398.00",
  "total_price": "398.00",
  "total_tax": "0.00",
  "total_weight": 1134,
  "currency": "USD",
  "completed_at": null,
  "closed_at": null,
  "user_id": null,
  "location_id": null,
  "source_identifier": null,
  "source_url": null,
  "device_id": null,
  "line_items": [
    {
      "applied_discounts": [
      ],
      "key": "620af35986d9bf455f434f064144c570",
      "compare_at_price": null,
      "destination_location_id": 938998167,
      "fulfillment_service": "manual",
      "gift_card": false,
      "grams": 567,
      "line_price": "199.00",
      "origin_location_id": 938998166,
      "price": "199.00",
      "product_id": 632910392,
      "properties": null,
      "quantity": 1,
      "requires_shipping": true,
      "sku": "IPOD2008PINK",
      "tax_lines": [
      ],
      "taxable": true,
      "title": "IPod Nano - 8GB",
      "variant_id": null,
      "variant_title": "",
      "vendor": "Apple"
    },
    {
      "applied_discounts": [
      ],
      "key": "620af35986d9bf455f434f064144c570",
      "compare_at_price": null,
      "destination_location_id": 938998167,
      "fulfillment_service": "manual",
      "gift_card": false,
      "grams": 567,
      "line_price": "199.00",
      "origin_location_id": 938998166,
      "price": "199.00",
      "product_id": 632910392,
      "properties": null,
      "quantity": 1,
      "requires_shipping": true,
      "sku": "IPOD2008PINK",
      "tax_lines": [
      ],
      "taxable": true,
      "title": "IPod Nano - 8GB",
      "variant_id": null,
      "variant_title": "",
      "vendor": "Apple"
    }
  ],
  "name": "#327474488104976385",
  "source": null,
  "discount_codes": [
  ],
  "abandoned_checkout_url": "https:\/\/checkout.local\/690933842\/checkouts\/123123123\/recover",
  "tax_lines": [
  ],
  "source_name": "web",
  "billing_address": {
    "first_name": "Bob",
    "address1": "123 Billing Street",
    "phone": "555-555-BILL",
    "city": "Billtown",
    "zip": "K2P0B0",
    "province": "Kentucky",
    "country": "United States",
    "last_name": "Biller",
    "address2": null,
    "company": "My Company",
    "latitude": null,
    "longitude": null,
    "name": "Bob Biller",
    "country_code": "US",
    "province_code": "KY"
  },
  "shipping_address": {
    "first_name": "Steve",
    "address1": "123 Shipping Street",
    "phone": "555-555-SHIP",
    "city": "Shippington",
    "zip": "K2P0S0",
    "province": "Kentucky",
    "country": "United States",
    "last_name": "Shipper",
    "address2": null,
    "company": "Shipping Company",
    "latitude": null,
    "longitude": null,
    "name": "Steve Shipper",
    "country_code": "US",
    "province_code": "KY"
  },
  "customer": {
    "id": 1234567,
    "email": "john@test.com",
    "accepts_marketing": false,
    "created_at": null,
    "updated_at": null,
    "first_name": "John",
    "last_name": "Smith",
    "orders_count": 0,
    "state": "disabled",
    "total_spent": "0.00",
    "last_order_id": null,
    "note": null,
    "verified_email": true,
    "multipass_identifier": null,
    "tax_exempt": false,
    "phone": null,
    "tags": "",
    "last_order_name": null
  }
}
Collection
collections/create, collections/delete, collections/update

{
  "id": 327474488104976386,
  "handle": "mynewcollection",
  "title": "My New Collection",
  "updated_at": "2017-03-20T16:04:30-04:00",
  "body_html": "<b>Some HTML<\/b>",
  "published_at": "2017-03-20T13:04:30-04:00",
  "sort_order": "manual",
  "template_suffix": null,
  "published_scope": "global"
}
CollectionPublication
collection_listings/add, collection_listings/remove, collection_listings/update

{
  "collection_listing": {
    "collection_id": 327474488104976386,
    "updated_at": null,
    "body_html": "<b>Some HTML<\/b>",
    "default_product_image": null,
    "handle": "mynewcollection",
    "image": null,
    "title": "My New Collection",
    "sort_order": "manual",
    "published_at": "2017-03-20T16:04:30-04:00"
  }
}
Customer
customers/create, customers/delete, customers/disable, customers/enable, customers/update

{
  "id": 1234567,
  "email": "bob@biller.com",
  "accepts_marketing": true,
  "created_at": null,
  "updated_at": null,
  "first_name": "Bob",
  "last_name": "Biller",
  "orders_count": 0,
  "state": "disabled",
  "total_spent": "0.00",
  "last_order_id": null,
  "note": "This customer loves ice cream",
  "verified_email": true,
  "multipass_identifier": null,
  "tax_exempt": false,
  "phone": null,
  "tags": "",
  "last_order_name": null,
  "addresses": [
  ]
}
CustomerSavedSearch
customer_groups/create, customer_groups/delete, customer_groups/update

{
  "id": 775454534,
  "name": "Repeat Customers",
  "created_at": "2017-03-20T16:04:30-04:00",
  "updated_at": "2017-03-20T16:04:30-04:00",
  "query": "orders_count:>1"
}
DraftOrder
draft_orders/create, draft_orders/delete, draft_orders/update

{
  "id": 123456,
  "note": null,
  "email": "jon@doe.ca",
  "taxes_included": false,
  "currency": "USD",
  "subtotal_price": "2537.00",
  "total_tax": "0.00",
  "total_price": "2702.22",
  "invoice_sent_at": null,
  "created_at": "2017-03-20T16:04:28-04:00",
  "updated_at": "2017-03-20T16:04:28-04:00",
  "tax_exempt": false,
  "completed_at": null,
  "name": "#D234",
  "status": "open",
  "line_items": [
    {
      "variant_id": 808950810,
      "product_id": 632910392,
      "title": "IPod Nano - 8GB",
      "variant_title": "Pink",
      "sku": "IPOD2008PINK",
      "vendor": "Apple",
      "price": "199.00",
      "grams": 567,
      "quantity": 3,
      "requires_shipping": true,
      "taxable": true,
      "gift_card": false,
      "fulfillment_service": "manual",
      "tax_lines": [
      ],
      "applied_discount": null,
      "name": "IPod Nano - 8GB - Pink",
      "properties": [
      ],
      "custom": false
    },
    {
      "variant_id": 808950810,
      "product_id": 632910392,
      "title": "IPod Nano - 8GB",
      "variant_title": "Pink",
      "sku": "IPOD2008PINK",
      "vendor": "Apple",
      "price": "199.00",
      "grams": 567,
      "quantity": 1,
      "requires_shipping": true,
      "taxable": true,
      "gift_card": false,
      "fulfillment_service": "manual",
      "tax_lines": [
      ],
      "applied_discount": null,
      "name": "IPod Nano - 8GB - Pink",
      "properties": [
      ],
      "custom": false
    },
    {
      "variant_id": 457924702,
      "product_id": 632910392,
      "title": "IPod Nano - 8GB",
      "variant_title": "Black",
      "sku": "IPOD2008BLACK",
      "vendor": "Apple",
      "price": "199.00",
      "grams": 567,
      "quantity": 10,
      "requires_shipping": true,
      "taxable": true,
      "gift_card": false,
      "fulfillment_service": "manual",
      "tax_lines": [
      ],
      "applied_discount": {
        "description": "bulk discount",
        "value": "10.0",
        "title": "Bulk Discount",
        "amount": "199.00",
        "value_type": "percentage"
      },
      "name": "IPod Nano - 8GB - Black",
      "properties": [
      ],
      "custom": false
    }
  ],
  "shipping_address": {
    "first_name": "Steve",
    "address1": "123 Shipping Street",
    "phone": "555-555-SHIP",
    "city": "Shippington",
    "zip": "40150",
    "province": "Kentucky",
    "country": "United States",
    "last_name": "Shipper",
    "address2": null,
    "company": "Shipping Company",
    "latitude": null,
    "longitude": null,
    "name": "Steve Shipper",
    "country_code": "US",
    "province_code": "KY"
  },
  "billing_address": {
    "first_name": "Bob",
    "address1": "123 Billing Street",
    "phone": "555-555-BILL",
    "city": "Billtown",
    "zip": "K2P0B0",
    "province": "Kentucky",
    "country": "United States",
    "last_name": "Biller",
    "address2": null,
    "company": "My Company",
    "latitude": null,
    "longitude": null,
    "name": "Bob Biller",
    "country_code": "US",
    "province_code": "KY"
  },
  "invoice_url": "https:\/\/checkout.local\/690933842\/invoices\/abcd1234abcd1234abcd1234abcd1234",
  "applied_discount": {
    "description": "loyalty",
    "value": "50.0",
    "title": "Loyalty",
    "amount": "50.00",
    "value_type": "fixed_amount"
  },
  "order_id": null,
  "shipping_line": {
    "title": "Generic Shipping",
    "price": "10.00",
    "custom": true,
    "handle": null
  },
  "tax_lines": [
    {
      "price": "35.82",
      "rate": 0.06,
      "title": "State Tax"
    },
    {
      "price": "11.94",
      "rate": 0.06,
      "title": "State Tax"
    },
    {
      "price": "107.46",
      "rate": 0.06,
      "title": "State Tax"
    }
  ],
  "tags": "",
  "note_attributes": [
  ],
  "customer": {
    "id": null,
    "email": "john@doe.ca",
    "accepts_marketing": false,
    "created_at": null,
    "updated_at": null,
    "first_name": "John",
    "last_name": "Smith",
    "orders_count": 0,
    "state": "disabled",
    "total_spent": "0.00",
    "last_order_id": null,
    "note": null,
    "verified_email": true,
    "multipass_identifier": null,
    "tax_exempt": false,
    "phone": null,
    "tags": "",
    "last_order_name": null,
    "default_address": {
      "id": null,
      "first_name": null,
      "last_name": null,
      "company": null,
      "address1": "123 Elm St.",
      "address2": null,
      "city": "Ottawa",
      "province": "Ontario",
      "country": "Canada",
      "zip": "K2H7A8",
      "phone": "123-123-1234",
      "name": "",
      "province_code": "ON",
      "country_code": "CA",
      "country_name": "Canada",
      "default": true
    }
  }
}
Fulfillment
fulfillments/create, fulfillments/update

{
  "id": 123456,
  "order_id": 123456,
  "status": "pending",
  "created_at": "2017-03-20T16:04:32-04:00",
  "service": null,
  "updated_at": "2017-03-20T16:04:32-04:00",
  "tracking_company": "UPS",
  "shipment_status": null,
  "email": "jon@doe.ca",
  "destination": {
    "first_name": "Steve",
    "address1": "123 Shipping Street",
    "phone": "555-555-SHIP",
    "city": "Shippington",
    "zip": "K2P0S0",
    "province": "Kentucky",
    "country": "United States",
    "last_name": "Shipper",
    "address2": null,
    "company": "Shipping Company",
    "latitude": null,
    "longitude": null,
    "name": "Steve Shipper",
    "country_code": "US",
    "province_code": "KY"
  },
  "tracking_number": "1z827wk74630",
  "tracking_numbers": [
    "1z827wk74630"
  ],
  "tracking_url": "http:\/\/wwwapps.ups.com\/etracking\/tracking.cgi?InquiryNumber1=1z827wk74630&TypeOfInquiryNumber=T&AcceptUPSLicenseAgreement=yes&submit=Track",
  "tracking_urls": [
    "http:\/\/wwwapps.ups.com\/etracking\/tracking.cgi?InquiryNumber1=1z827wk74630&TypeOfInquiryNumber=T&AcceptUPSLicenseAgreement=yes&submit=Track"
  ],
  "receipt": {
  },
  "line_items": [
    {
      "id": 808950810,
      "variant_id": null,
      "title": "IPod Nano - 8GB",
      "quantity": 1,
      "price": "199.00",
      "grams": 567,
      "sku": "IPOD2008PINK",
      "variant_title": null,
      "vendor": null,
      "fulfillment_service": "manual",
      "product_id": 632910392,
      "requires_shipping": true,
      "taxable": true,
      "gift_card": false,
      "name": "IPod Nano - 8GB",
      "variant_inventory_management": null,
      "properties": [
      ],
      "product_exists": true,
      "fulfillable_quantity": 1,
      "total_discount": "0.00",
      "fulfillment_status": null,
      "tax_lines": [
      ]
    },
    {
      "id": 199,
      "variant_id": null,
      "title": "IPod Nano - 8GB",
      "quantity": 1,
      "price": "199.00",
      "grams": 567,
      "sku": "IPOD2008PINK",
      "variant_title": null,
      "vendor": null,
      "fulfillment_service": "manual",
      "product_id": 632910392,
      "requires_shipping": true,
      "taxable": true,
      "gift_card": false,
      "name": "IPod Nano - 8GB",
      "variant_inventory_management": null,
      "properties": [
      ],
      "product_exists": true,
      "fulfillable_quantity": 1,
      "total_discount": "5.00",
      "fulfillment_status": null,
      "tax_lines": [
      ]
    }
  ]
}
FulfillmentEvent
fulfillment_events/create, fulfillment_events/delete

{
  "id": 1234567,
  "fulfillment_id": 123456,
  "status": "in_transit",
  "message": "Item is now in transit",
  "happened_at": "2017-03-20T16:04:31-04:00",
  "city": "Montreal",
  "province": "QC",
  "country": "CA",
  "zip": null,
  "address1": null,
  "latitude": null,
  "longitude": null,
  "shop_id": 690933842,
  "created_at": "2017-03-20T16:04:31-04:00",
  "updated_at": "2017-03-20T16:04:31-04:00",
  "estimated_delivery_at": null,
  "order_id": 123456
}
Order
orders/cancelled, orders/create, orders/delete, orders/fulfilled, orders/paid, orders/partially_fulfilled, orders/updated

{
  "id": 123456,
  "email": "jon@doe.ca",
  "closed_at": null,
  "created_at": "2017-03-20T16:02:31-04:00",
  "updated_at": "2017-03-20T16:02:31-04:00",
  "number": 234,
  "note": null,
  "token": "123456abcd",
  "gateway": null,
  "test": true,
  "total_price": "403.00",
  "subtotal_price": "393.00",
  "total_weight": 0,
  "total_tax": "0.00",
  "taxes_included": false,
  "currency": "USD",
  "financial_status": "voided",
  "confirmed": false,
  "total_discounts": "5.00",
  "total_line_items_price": "398.00",
  "cart_token": null,
  "buyer_accepts_marketing": true,
  "name": "#9999",
  "referring_site": null,
  "landing_site": null,
  "cancelled_at": "2017-03-20T16:02:31-04:00",
  "cancel_reason": "customer",
  "total_price_usd": null,
  "checkout_token": null,
  "reference": null,
  "user_id": null,
  "location_id": null,
  "source_identifier": null,
  "source_url": null,
  "processed_at": null,
  "device_id": null,
  "browser_ip": null,
  "landing_site_ref": null,
  "order_number": 1234,
  "discount_codes": [
  ],
  "note_attributes": [
  ],
  "payment_gateway_names": [
    "visa",
    "bogus"
  ],
  "processing_method": "",
  "checkout_id": null,
  "source_name": "web",
  "fulfillment_status": "pending",
  "tax_lines": [
  ],
  "tags": "",
  "contact_email": "jon@doe.ca",
  "order_status_url": null,
  "line_items": [
    {
      "id": 808950810,
      "variant_id": null,
      "title": "IPod Nano - 8GB",
      "quantity": 1,
      "price": "199.00",
      "grams": 567,
      "sku": "IPOD2008PINK",
      "variant_title": null,
      "vendor": null,
      "fulfillment_service": "manual",
      "product_id": 632910392,
      "requires_shipping": true,
      "taxable": true,
      "gift_card": false,
      "name": "IPod Nano - 8GB",
      "variant_inventory_management": null,
      "properties": [
      ],
      "product_exists": true,
      "fulfillable_quantity": 1,
      "total_discount": "0.00",
      "fulfillment_status": null,
      "tax_lines": [
      ]
    },
    {
      "id": 199,
      "variant_id": null,
      "title": "IPod Nano - 8GB",
      "quantity": 1,
      "price": "199.00",
      "grams": 567,
      "sku": "IPOD2008PINK",
      "variant_title": null,
      "vendor": null,
      "fulfillment_service": "manual",
      "product_id": 632910392,
      "requires_shipping": true,
      "taxable": true,
      "gift_card": false,
      "name": "IPod Nano - 8GB",
      "variant_inventory_management": null,
      "properties": [
      ],
      "product_exists": true,
      "fulfillable_quantity": 1,
      "total_discount": "5.00",
      "fulfillment_status": null,
      "tax_lines": [
      ]
    }
  ],
  "shipping_lines": [
    {
      "id": 1234567,
      "title": "Generic Shipping",
      "price": "10.00",
      "code": null,
      "source": "spiffy",
      "phone": null,
      "requested_fulfillment_service_id": null,
      "delivery_category": null,
      "carrier_identifier": null,
      "tax_lines": [
      ]
    }
  ],
  "billing_address": {
    "first_name": "Bob",
    "address1": "123 Billing Street",
    "phone": "555-555-BILL",
    "city": "Billtown",
    "zip": "K2P0B0",
    "province": "Kentucky",
    "country": "United States",
    "last_name": "Biller",
    "address2": null,
    "company": "My Company",
    "latitude": null,
    "longitude": null,
    "name": "Bob Biller",
    "country_code": "US",
    "province_code": "KY"
  },
  "shipping_address": {
    "first_name": "Steve",
    "address1": "123 Shipping Street",
    "phone": "555-555-SHIP",
    "city": "Shippington",
    "zip": "K2P0S0",
    "province": "Kentucky",
    "country": "United States",
    "last_name": "Shipper",
    "address2": null,
    "company": "Shipping Company",
    "latitude": null,
    "longitude": null,
    "name": "Steve Shipper",
    "country_code": "US",
    "province_code": "KY"
  },
  "fulfillments": [
  ],
  "refunds": [
  ],
  "customer": {
    "id": 1234567,
    "email": "john@test.com",
    "accepts_marketing": false,
    "created_at": null,
    "updated_at": null,
    "first_name": "John",
    "last_name": "Smith",
    "orders_count": 0,
    "state": "disabled",
    "total_spent": "0.00",
    "last_order_id": null,
    "note": null,
    "verified_email": true,
    "multipass_identifier": null,
    "tax_exempt": false,
    "phone": null,
    "tags": "",
    "last_order_name": null,
    "default_address": {
      "id": 1234567,
      "first_name": null,
      "last_name": null,
      "company": null,
      "address1": "123 Elm St.",
      "address2": null,
      "city": "Ottawa",
      "province": "Ontario",
      "country": "Canada",
      "zip": "K2H7A8",
      "phone": "123-123-1234",
      "name": "",
      "province_code": "ON",
      "country_code": "CA",
      "country_name": "Canada",
      "default": false
    }
  }
}
OrderTransaction
order_transactions/create

{
  "id": 23456,
  "order_id": 123456,
  "amount": "11.50",
  "kind": "authorization",
  "gateway": "visa",
  "status": "success",
  "message": null,
  "created_at": "2017-03-20T16:02:33-04:00",
  "test": false,
  "authorization": "1001",
  "currency": null,
  "location_id": null,
  "user_id": null,
  "parent_id": null,
  "device_id": null,
  "receipt": {
  },
  "error_code": null,
  "source_name": "web",
  "payment_details": {
    "credit_card_bin": null,
    "avs_result_code": null,
    "cvv_result_code": null,
    "credit_card_number": "•••• •••• •••• 1234",
    "credit_card_company": "Visa"
  }
}
Product
products/create, products/delete, products/update

{
  "id": 327475578523353102,
  "title": "Example T-Shirt",
  "body_html": null,
  "vendor": "Acme",
  "product_type": "Shirts",
  "created_at": null,
  "handle": "example-t-shirt",
  "updated_at": null,
  "published_at": "2017-03-20T16:04:28-04:00",
  "template_suffix": null,
  "published_scope": "global",
  "tags": "mens t-shirt example",
  "variants": [
    {
      "id": 1234567,
      "product_id": 327475578523353102,
      "title": "",
      "price": "19.99",
      "sku": "example-shirt-s",
      "position": 0,
      "grams": 200,
      "inventory_policy": "deny",
      "compare_at_price": "24.99",
      "fulfillment_service": "manual",
      "inventory_management": null,
      "option1": "Small",
      "option2": null,
      "option3": null,
      "created_at": null,
      "updated_at": null,
      "taxable": true,
      "barcode": null,
      "image_id": null,
      "inventory_quantity": 75,
      "weight": 0.44,
      "weight_unit": "lb",
      "old_inventory_quantity": 75,
      "requires_shipping": true
    },
    {
      "id": 1234568,
      "product_id": 327475578523353102,
      "title": "",
      "price": "19.99",
      "sku": "example-shirt-m",
      "position": 0,
      "grams": 200,
      "inventory_policy": "deny",
      "compare_at_price": "24.99",
      "fulfillment_service": "manual",
      "inventory_management": "spiffy",
      "option1": "Medium",
      "option2": null,
      "option3": null,
      "created_at": null,
      "updated_at": null,
      "taxable": true,
      "barcode": null,
      "image_id": null,
      "inventory_quantity": 50,
      "weight": 0.44,
      "weight_unit": "lb",
      "old_inventory_quantity": 50,
      "requires_shipping": true
    }
  ],
  "options": [
    {
      "id": 12345,
      "product_id": 327475578523353102,
      "name": "Title",
      "position": 1,
      "values": [
        "Small",
        "Medium"
      ]
    }
  ],
  "images": [
    {
      "id": 1234567,
      "product_id": 327475578523353102,
      "position": 0,
      "created_at": null,
      "updated_at": null,
      "src": "\/\/cdn.spiffy.com\/s\/assets\/spiffy_shirt-39bb555874ecaeed0a1170417d58bbcf792f7ceb56acfe758384f788710ba635.png",
      "variant_ids": [
      ]
    }
  ],
  "image": null
}
ProductPublication
product_listings/add, product_listings/remove, product_listings/update

{
  "product_listing": {
    "product_id": 327475578523353102,
    "created_at": null,
    "updated_at": null,
    "body_html": null,
    "handle": "example-t-shirt",
    "product_type": "Shirts",
    "title": "Example T-Shirt",
    "vendor": "Acme",
    "available": true,
    "tags": "mens t-shirt example",
    "published_at": "2017-03-20T16:02:34-04:00",
    "images": [
      {
        "id": 1234567,
        "created_at": null,
        "position": 0,
        "updated_at": null,
        "product_id": 327475578523353102,
        "src": "\/\/cdn.spiffy.com\/s\/assets\/spiffy_shirt-39bb555874ecaeed0a1170417d58bbcf792f7ceb56acfe758384f788710ba635.png",
        "variant_ids": [
        ]
      }
    ],
    "options": [
      {
        "id": 12345,
        "name": "Title",
        "product_id": 327475578523353102,
        "position": 1
      }
    ],
    "variants": [
      {
        "id": 1234567,
        "title": "",
        "option_values": [
          {
            "option_id": 12345,
            "name": "Title",
            "value": "Small"
          }
        ],
        "price": "19.99",
        "formatted_price": "$19.99",
        "compare_at_price": "24.99",
        "grams": 200,
        "requires_shipping": true,
        "sku": "example-shirt-s",
        "barcode": null,
        "taxable": true,
        "position": 0,
        "available": true,
        "inventory_policy": "deny",
        "inventory_quantity": 75,
        "inventory_management": null,
        "fulfillment_service": "manual",
        "weight": 0.44,
        "weight_unit": "lb",
        "image_id": null,
        "created_at": null,
        "updated_at": null
      },
      {
        "id": 1234568,
        "title": "",
        "option_values": [
          {
            "option_id": 12345,
            "name": "Title",
            "value": "Medium"
          }
        ],
        "price": "19.99",
        "formatted_price": "$19.99",
        "compare_at_price": "24.99",
        "grams": 200,
        "requires_shipping": true,
        "sku": "example-shirt-m",
        "barcode": null,
        "taxable": true,
        "position": 0,
        "available": true,
        "inventory_policy": "deny",
        "inventory_quantity": 50,
        "inventory_management": "spiffy",
        "fulfillment_service": "manual",
        "weight": 0.44,
        "weight_unit": "lb",
        "image_id": null,
        "created_at": null,
        "updated_at": null
      }
    ]
  }
}
Refund
refunds/create

{
  "id": 1234567,
  "order_id": 123456,
  "created_at": "2017-03-20T16:02:33-04:00",
  "note": "Things were damaged",
  "restock": true,
  "user_id": 799407056,
  "processed_at": "2017-03-20T16:02:33-04:00",
  "refund_line_items": [
    {
      "id": 808950883,
      "quantity": 1,
      "line_item_id": 808950810,
      "subtotal": 199.0,
      "total_tax": 0.0,
      "line_item": {
        "id": 808950810,
        "variant_id": null,
        "title": "IPod Nano - 8GB",
        "quantity": 1,
        "price": "199.00",
        "grams": 567,
        "sku": "IPOD2008PINK",
        "variant_title": null,
        "vendor": null,
        "fulfillment_service": "manual",
        "product_id": 632910392,
        "requires_shipping": true,
        "taxable": true,
        "gift_card": false,
        "name": "IPod Nano - 8GB",
        "variant_inventory_management": null,
        "properties": [
        ],
        "product_exists": true,
        "fulfillable_quantity": 1,
        "total_discount": "0.00",
        "fulfillment_status": null,
        "tax_lines": [
        ]
      }
    },
    {
      "id": 272,
      "quantity": 1,
      "line_item_id": 199,
      "subtotal": 194.0,
      "total_tax": 0.0,
      "line_item": {
        "id": 199,
        "variant_id": null,
        "title": "IPod Nano - 8GB",
        "quantity": 1,
        "price": "199.00",
        "grams": 567,
        "sku": "IPOD2008PINK",
        "variant_title": null,
        "vendor": null,
        "fulfillment_service": "manual",
        "product_id": 632910392,
        "requires_shipping": true,
        "taxable": true,
        "gift_card": false,
        "name": "IPod Nano - 8GB",
        "variant_inventory_management": null,
        "properties": [
        ],
        "product_exists": true,
        "fulfillable_quantity": 1,
        "total_discount": "5.00",
        "fulfillment_status": null,
        "tax_lines": [
        ]
      }
    }
  ],
  "transactions": [
    {
      "id": 42424242,
      "order_id": 123456,
      "amount": "75.00",
      "kind": "refund",
      "gateway": "bogus",
      "status": "success",
      "message": "This is a refund",
      "created_at": null,
      "test": false,
      "authorization": null,
      "currency": null,
      "location_id": null,
      "user_id": null,
      "parent_id": null,
      "device_id": null,
      "receipt": {
      },
      "error_code": null,
      "source_name": "web"
    },
    {
      "id": 42424243,
      "order_id": 123456,
      "amount": "10.00",
      "kind": "refund",
      "gateway": "bogus",
      "status": "success",
      "message": null,
      "created_at": null,
      "test": false,
      "authorization": null,
      "currency": null,
      "location_id": null,
      "user_id": null,
      "parent_id": null,
      "device_id": null,
      "receipt": {
      },
      "error_code": null,
      "source_name": "web"
    }
  ],
  "order_adjustments": [
  ]
}
Shop
app/uninstalled, shop/update

{
  "id": 1234567,
  "name": "Super Toys",
  "email": "super@supertoys.com",
  "domain": null,
  "created_at": null,
  "province": "Tennessee",
  "country": "US",
  "address1": "190 MacLaren Street",
  "zip": "37178",
  "city": "Houston",
  "source": null,
  "phone": "3213213210",
  "updated_at": null,
  "customer_email": null,
  "latitude": null,
  "longitude": null,
  "primary_location_id": null,
  "primary_locale": "en",
  "address2": null,
  "country_code": "US",
  "country_name": "United States",
  "currency": "USD",
  "timezone": "(GMT-05:00) Eastern Time (US & Canada)",
  "iana_timezone": null,
  "shop_owner": "N\/A",
  "money_format": "$",
  "money_with_currency_format": "$ USD",
  "weight_unit": "kg",
  "province_code": "TN",
  "taxes_included": null,
  "tax_shipping": null,
  "county_taxes": null,
  "plan_display_name": null,
  "plan_name": null,
  "has_discounts": null,
  "has_gift_cards": false,
  "spiffy_domain": null,
  "google_apps_domain": null,
  "google_apps_login_enabled": null,
  "money_in_emails_format": "$",
  "money_with_currency_in_emails_format": "$ USD",
  "eligible_for_payments": true,
  "requires_extra_payments_agreement": false,
  "password_enabled": null,
  "has_storefront": false,
  "eligible_for_card_reader_giveaway": false,
  "finances": true,
  "setup_required": false,
  "force_ssl": false
}
Theme
 themes/create, themes/delete, themes/publish, themes/update 

{
  "id": null,
  "name": "Comfort",
  "created_at": "2017-03-20T16:02:33-04:00",
  "updated_at": "2017-03-20T16:02:33-04:00",
  "role": "main",
  "theme_store_id": 1234,
  "previewable": true,
  "processing": false
}


What you can do with a Webhook


The Spiffy Stores API lets you do the following with the Webhook resource. More detailed versions of these general actions may be available:

  • GET /admin/webhooks.json
    Receive a list of all Webhooks

  • GET /admin/webhooks/count.json?topic=orders/create
    Receive a count of all Webhooks

  • GET /admin/webhooks/#{id}.json
    Receive a single Webhook

  • POST /admin/webhooks.json
    Create a new Webhook

  • PUT /admin/webhooks/#{id}.json
    Modify an existing Webhook

  • DELETE /admin/webhooks/#{id}.json
    Remove a Webhook from the database


Webhook properties

id
{ "id": 901431826 }

The unique numeric identifier for the webhook.

address
{ "address": "https://apple.com/uninstall" }

The URI where the webhook should send the POST request when the event occurs.

format
{ "format": "json" }

The format in which the webhook should send the data. Valid values are json and xml.

topic
{ "topic": "app/uninstalled" }

The event that will trigger the webhook. Valid values are:

  • app/uninstalled
  • carts/create
  • carts/update
  • checkouts/create
  • checkouts/delete
  • checkouts/update
  • collection_listings/add
  • collection_listings/remove
  • collection_listings/update
  • collections/create
  • collections/delete
  • collections/update
  • customer_groups/create
  • customer_groups/delete
  • customer_groups/update
  • customers/create
  • customers/delete
  • customers/disable
  • customers/enable
  • customers/update
  • draft_orders/create
  • draft_orders/delete
  • draft_orders/update
  • fulfillment_events/create
  • fulfillment_events/delete
  • fulfillments/create
  • fulfillments/update
  • order_transactions/create
  • orders/cancelled
  • orders/create
  • orders/delete
  • orders/fulfilled
  • orders/paid
  • orders/partially_fulfilled
  • orders/updated
  • product_listings/add
  • product_listings/remove
  • product_listings/update
  • products/create
  • products/delete
  • products/update
  • refunds/create
  • shop/update
  • themes/create
  • themes/delete
  • themes/publish
  • themes/update
source
{ "source": "api" }

The source which created the webhook. Valid values are api and manual.

created_at
{ "created_at": "2012-09-28T11:50:07-04:00" }

The date and time when the webhook was created. The API returns this value in ISO 8601 format.

updated_at
{ "updated_at": "2012-09-28T11:50:07-04:00" }

The date and time when the webhook was updated. The API returns this value in ISO 8601 format.

Endpoints

GET /api/webhooks.json

Get a list of webhooks.

Optional Parameters

limit Number of results returned. The default is 30, with a maximum of 50 in a single request.
page The number of the page to return. The number of results per page is set by the limit parameter. If more results are required, then submit the request again, increasing the page number each time.
since_id Limit the results to only include objects which have an id greater than the given value.
address Limit the results to only include webhooks with the given address (URI).
topic Limit the results to only include webhooks with the given topic.
source Limit the results to only include webhooks with the given source.
created_at_min Return only the webhooks created after the given date and time. Use the format "2014-12-31 12:00".
created_at_max Return only the webhooks created before the given date and time. Use the format "2014-12-31 12:00".
updated_at_min Return only the webhooks updated after the given date and time. Use the format "2014-12-31 12:00".
updated_at_max Return only the webhooks updated before the given date and time. Use the format "2014-12-31 12:00".
fields A comma-separated list of fields to return in the response.

Example Request and Response

GET /api/webhooks.json

HTTP/1.1 200 OK
{
  "webhooks": [
    {
      "id": 4759306,
      "address": "https:\/\/apple.com",
      "topic": "orders\/create",
      "created_at": "2017-03-20T16:02:17-04:00",
      "updated_at": "2017-03-20T16:02:17-04:00",
      "format": "json"
    },
    ...
  ]
}

Examples using filters

GET /api/webhooks.json?fields=id,address

GET /api/webhooks.json?since_id=4759306

GET /api/webhooks/count.json

Return a count of the number of webhooks.

Optional Parameters

since_id Limit the results to only include objects which have an id greater than the given value.
address Limit the results to only include webhooks with the given address (URI).
topic Limit the results to only include webhooks with the given topic.
source Limit the results to only include webhooks with the given source.
created_at_min Return only the webhooks created after the given date and time. Use the format "2014-12-31 12:00".
created_at_max Return only the webhooks created before the given date and time. Use the format "2014-12-31 12:00".
updated_at_min Return only the webhooks updated after the given date and time. Use the format "2014-12-31 12:00".
updated_at_max Return only the webhooks updated before the given date and time. Use the format "2014-12-31 12:00".

Example Request and Response

GET /api/webhooks/count.json

HTTP/1.1 200 OK

{
  "count": 15
}

Examples using filters

GET /api/webhooks/count.json?topic=orders/create

GET /api/webhooks/WEBHOOK_ID.json

Retrieves a single webhook by ID.

Optional Parameters

fields A comma-separated list of fields to return in the response.

Example Request and Response

GET /api/webhooks/248.json

HTTP/1.1 200 OK

{
  "webhook": {
    "id": 248,
    "address": "https://mytestapps.com.au/webhooks/app_uninstalled",
    "created_at": "2016-10-13T16:16:52.210+11:00",
    "updated_at": "2016-10-13T16:16:52.210+11:00",
    "format": "json",
    "topic": "app/uninstalled"
  }
}

POST /api/webhooks.json

Create a webhook subscription by specifying both an address and a topic. This API call can be used by apps to install any notifications that the app needs.

Example Request and Response

POST /api/webhooks.json

{
  "webhook": {
    "topic": "orders/create",
    "address": "https://whatever.hostname.com/",
    "format": "json"
  }
}

HTTP/1.1 201 Created

{
  "webhook": {
    "id": 1047897619,
    "address": "http://whatever.hostname.com/",
    "topic": "orders/create",
    "created_at": "2017-03-20T16:02:33-04:00",
    "updated_at": "2017-03-20T16:02:33-04:00",
    "format": "json"
  }
}

PUT /api/webhooks/WEBHOOK_ID.json

Update a webhook subscription's topic or address URIs.

Example Request and Response

PUT /api/webhooks/4759306.json

{
  "webhook": {
    "id": 4759306,
    "address": "https://somewhere-else.com/"
  }
}

HTTP/1.1 200 OK

{
  "webhook": {
    "id": 4759306,
    "address": "http://somewhere-else.com/",
    "topic": "orders/create",
    "created_at": "2017-03-20T16:02:17-04:00",
    "updated_at": "2017-03-20T16:04:29-04:00",
    "format": "json"
  }
}

DELETE /api/webhooks/WEBHOOK_ID.json

Delete a webhook.

Example Request and Response

DELETE /api/webhooks/234548.json

HTTP/1.1 200 OK

{}

Further Reference