Skip to content

API Documentation: Objects: Webhook

Patrick Thill edited this page Feb 1, 2014 · 12 revisions

Go back to read introductory information and usage guidelines about the API.

Object name

Webhook

Associated Capabilities

{none}

Object Description

A Webhook is a request by a third-party app to be notified of events in the stores their apps are serving.

Right now, the only supported event is app uninstallation.

Webhooks can be created, viewed, updated and deleted through a REST API similar to that used by Script Tags and Blobs. Each webhook created must include a publicly-visible url to which a POST request should be sent upon the event occurring.

Object Attributes

Field Description Notes
id The unique id for this webhook.
format The format for the webhook POST body data. Currently, only 'json'.
topic The name of the event on which this webhook should be fired. Currently, only 'app/uninstalled'.
address The url that should be posted to when the event occurs.
created_at The date that the webhook was created. Format: ISO 8601
updated_at The date the webhook was last updated. Format: ISO 8601

Receiving Fired Webhooks

When the requested event occurs, a POST request is sent to the url given in the webhook. This request will have several special headers:

x-lexity-nonce: A single-use string for verification, which can otherwise be ignored.
x-lexity-topic: The topic of the webhook.
x-lexity-app-token: Your app's token.
x-lexity-store-id: The lexity store id of the store with your app installed for which this webhook is being fired.
x-lexity-hmac: A base 64 encoded string used for verification.

The body of the request will be formatted according to the format field with which the webhook was registered. It will contain data pertinent to the specific topic; for 'app/uninstalled' this is just a unix timestamp of the time when the app was uninstalled. Note that webhooks will be sent soon after the event occurs, but not immediately, and so the timestamp may be a few minutes old already when you receive it.

In this version of the API, webhooks are only fired once; if the machine that you have listening for webhooks goes down it would be prudent to poll your stores to see if anything has changed.

Verifying webhooks

Each POST request generated by firing a webhook will have an x-lexity-hmac header which can be used to verify that the webhook did in fact come from Lexity. This field is a base 64 encoded SHA-256 hash of the special headers (in header_name=header_value format) and body of the message, concatenated together, using your app's app_secret as the key.

For example, the following Ruby code (using the OpenSSL and Base64 libraries) will compute the hmac header, after you have parsed the headers into a ruby hash:

digest = OpenSSL::Digest::Digest.new('sha256')
sorted_headers = headers.except("x-lexity-hmac").select{|k,v| k.start_with?("x-lexity")}.collect{|k,v| "#{k}=#{v}"}.sort.join
hmac = Base64.encode64(OpenSSL::HMAC.digest(digest, app.app_secret, sorted_headers + body)).strip

To verify that the webhook actually came from Lexity, simply calculate the message authentication code as above and check that the hmac value you calculate is equal to the value of the x-lexity-hmac header. Note that the sort in this code is the ruby builtin sort, so in particular it sorts capital letters before all lowercase letters (by their ASCII value).

Query Parameters Available for this Object:

Field Description Notes
format Only show webhooks with format equal to this value.
address Only show webhooks with address equal to this value.
topic Only show webhooks with topic equal to this value.
limit Limit of number of objects in the response. Defaults to 50, maximum allowed value is 250.
page For paginated responses, the page to show. Defaults to 1.
fields Comma-separated string with the fields to be returned in the response body. Returns all fields by default.

Available API Interactions

Get all webhooks for a store

Request

GET {base_url}/webhooks.json

Request data

(empty)

Example response

HTTP/1.1 200 OK

{
    "webhooks": [{
        "created_at": "2012-12-08T02:14:56Z",
        "updated_at": "2012-12-08T02:14:56Z",
        "id": 56,
        "format": "json",
        "address": "http://example.com/uninstalled",
        "topic": "app/uninstalled"
    }, {
        "created_at": "2012-12-09T01:09:12Z",
        "updated_at": "2012-12-10T03:54:33Z",
        "id": 57,
        "format": "json",
        "address": "http://other.example.com/uninstalled",
        "topic": "app/uninstsalled"
    }]
}

Create a new webhook

Request

POST {base_url}/webhooks.json

Request data

{
    "webhook": {
        "format": "json",
        "address": "http://yetanother.example.com/uninstalled",
        "topic": "app/uninstalled"
    }
}

Example response

HTTP/1.1 201 Created

{
    "webhook": {
        "created_at": "2012-12-12T20:02:39Z",
        "updated_at": "2012-12-12T20:02:39Z",
        "id": 58,
        "format": "json",
        "address": "http://yetanother.example.com/uninstalled",
        "topic": "app/uninstalled"
    }
}

Count webhooks

Request

GET {base_url}/webhooks/count.json

Request data

(empty)

Example response

HTTP/1.1 200 OK

{
  "count": 3
}

Edit a webhook

Request

PUT {base_url}/webhooks/{id}.json

Request data

{
  "webhook": {
    "address": "http://yet.another.example.com/uninstalled"
  }
}

Example response

HTTP/1.1 200 OK

{
    "webhook": {
        "created_at": "2012-12-12T20:02:39Z",
        "updated_at": "2012-12-12T20:02:39Z",
        "id": 58,
        "format": "json",
        "address": "http://other.example.com/uninstalled",
        "topic": "app/uninstalled"
    }
}

Delete a webhook

Request

DELETE {base_url}/webhooks/{id}.json

Request data

(empty)

Example response

HTTP/1.1 200 OK

{}