Web Hook

Web hooks are accessed via /api/webhook. They represent an asynchronous callback to an external API and are triggered by various events in our site.

They work like this:

Step 1: Subscribe

You set up your application to subscribe to a particular event type in our system via this API.

Step 2: Event is Triggered

Let's say you subscribe to the ReceiptShipped event. When this event is triggered and it matches your User id then we proceed to step 3.

Step 3: Callback

Our system sends an HTTP Post to an endpoint of your choosing via a callback_uri, letting you know that the event has occured.

Step 4: Verify

We'll send a signature which is signed using your private APIKey so that you can verify the post is authentic.

Events

The following web hook events are available for you to subscribe to.

Item Sold

Triggered when a Game has been sold. The payload will be as follows:

 {
     "item" : {
       "quantity" : 1,
       "name" : "Adrift",
       "sku_id" : "361B3436-E1EA-11E4-BB8E-E1C477A16DD8",
       "price_each" : "28.14",
       "shop_uri" : "/games/adrift",
       ...
     },
     "shipping_address" : {
         "city" : "Madison",
         "state" : "WI",
         "country" : "United States",
     }
 }
Required Parameters
event

ItemSold

owner_class

Designer

owner_id

The id of a Designer you control.

Receipt Refunded

Triggered when a Receipt has been refunded. The payload posted will be a Receipt object.

Required Parameters
event

ReceiptRefunded

owner_class

User

owner_id

Your User id.

Receipt Shipped

Triggered when a Receipt has been marked shipped. The payload posted will be a Receipt object with _include=shipments enabled.

Required Parameters
event

ReceiptShipped

owner_class

User

owner_id

Your User id.

Properties

Complete details in WebHookProperties.

id

The unique id for this web hook. It will never change.

wing_object_type

webhook.

owner_class

The object class in our system that you must have edit access to in order to subscribe to a particular event.

owner_id

The instance id of the class that you own.

event

See the list of Events above for details.

callback_uri

The URL endpoint where the HTTP Post operation will be submitted.

api_key_id

The APIKey id that will be used to sign the post to prevent third-parties from faking posts to your endpoint.

Methods

The methods used to fetch and manipulate web hooks.

List

 GET /api/user/xxx/webhooks

See User for details.

Fetch

 GET /api/webhook/xxx
session_id

Required. The unique session id provided by a Session method.

Returns:

 {
   "id" : "xxx",
   "event" : "ItemSold",
   ...
 }

Create / Subscribe

 POST /api/webhook
session_id

Required. The unique session id provided by a Session method.

owner_class

Required. See the list of Events above for details.

owner_id

Required. See the list of Events above for details.

event

Required. See the list of Events above for details.

callback_uri

Required. The URL endpoint where the HTTP Post operation will be submitted.

api_key_id

The APIKey id that will be used to sign the post to prevent third-parties from faking posts to your endpoint.

Returns:

 {
   "id" : "xxx",
   "event" : "ItemSold",
   ...
 }

Update

 PUT /api/webhook/xxx
session_id

Required. The unique session id provided by a Session method.

owner_class

Required. See the list of Events above for details.

owner_id

Required. See the list of Events above for details.

event

Required. See the list of Events above for details.

callback_uri

Required. The URL endpoint where the HTTP Post operation will be submitted.

api_key_id

The APIKey id that will be used to sign the post to prevent third-parties from faking posts to your endpoint.

Returns:

 {
   "id" : "xxx",
   "event" : "ItemSold",
   ...
 }

Delete / Unsubscribe

 DELETE /api/webhook/xxx
session_id

Required. The unique session id provided by a Session method.

Returns:

 {
   "success" : 1
 }

Test

Calling this method will cause our servers to process a webhook back to your callback_uri with a type of test.

 POST /api/webhook/xxx/test
session_id

Required. The unique session id provided by a Session method.

payload

Required. A JSON encoded object.

Returns:

 1 || 0

Callbacks

A callback is the HTTP Post operation performed by a web hook to the callback_uri endpoint that you set when you subscribe to a web hook.

Post Body

The callback will come to your server in the form of an HTTP POST with the following form parameters:

epoch

The number of seconds since January 1, 1970 UTC. You can use this to determine if the message is close enough to your server's time be considered in tolerance. This can be useful for preventing hackers from sending fake messages your way.

message

A JSON encoded string of the message object sent from this web hook.

id

The unique id of this web hook.

owner_class

The owner_class defined as part of this web hook.

owner_id

The owner_id defined as part of this web hook.

event

The event name defined as part of this web hook.

payload

An object of the original data that we're sending you generated from the event.

type

Can be one of 4 types: subscribe, unsubscribe, data, test.

subscribe

When you first create the web hook. Will have an empty payload.

unsubscribe

When you or the system deletes the web hook. Will have an empty payload.

data

When the real event is fired it will be of type data and the payload will have real data in it.

test

When you call the Test method described above. Will have the payload you define.

hmac

A SHA256 hex encoded HMAC signature. You can use this to verify that the callback came from us.

Post Body Example

  {
    'hmac' => '02e605c1a27fc8263b8fd187b517df85ef59aab118b71979fbaa20c9e297e290',
    'message' => '{"owner_id":"795AD480-328E-11E2-B41A-9E208588C839","event":"OrderShipped","type":"test","payload":{"foo":"bar"},"owner_class":"User", "id" : "9E208588C839-3313-333-331133"}',
    'epoch' => '1613851807'
  }

Verify the Message

Once you have an end point exposed to receive these callbacks anybody could send a message your way. To verify it came from us use you can use our HMAC signature. You do that using the following procedure.

Step 1: Prepare the signature string

Create the signature string oncatenating the epoch, the character ., and the message (leave it as a JSON string) together.

Step 2: Determine the expected signature

Compute an HMAC with the SHA256 hash function. Use the your private_key from the APIKey associated with this subscription as the key and used the signature string you created in step 1 as the message.

Step 3: Compare

Compare the output of the HMAC you just generated with the hmac from the message. Remember that the hmac we send is hex encoded so yours should be too in order to compare.

Step 4: Timing (optional)

You can also check the epoch we sent you with your local server time to protect against timing attacks.

Fault Tolerance

Just like we expect you to build your application to be tolerant of any outages we may have, we don't expect your app to have 100% uptime either. Therefore web hooks will automatically retry upon failure.

200 = Success

Only an HTTP response code of 200 is considered a success. Anything else is considered a failure. If we receive a 200 then you'll never get the the callback again. If we get anything other than 200 we'll start retrying using the rules below.

Cascading Retries

The first retry will happen approximately 1 hour after the first failure. The second retry will happen 2 hours after the second failure. The third retry will happen 3 hours after the 3rd failure, and so on. Which means that by the time you get to the fourth retry, 6 hours have elapsed.

That said, subsequent events alter this cascading. For example, if one event has already failed, and another event using the same web hook is triggered and succeeds, then the fail count is reset and subsequent retries of past failures will happen faster. Likewise, if a secondary event using the same web hook fails, then it will increment the fail count and thus the cascade will happen faster. Thus, if you have 5 events happen in rapid succession all using the same web hook then the 5th one will have it's retry delay set to 5 hours before its first retry, because the failure count is attached to the web hook not the instance of the event.

Checking Status

You can check on the status of a web hook by using the Fetch method above. There you can see the failures_since_last_success property to see how far it has cascaded. Also the date_updated property will tell you the time of the last retry. You cannot, however, check on the status of the individual event instances. You just have to wait for their delays to fire and run their next attempt.

Updating Web Hook Before Retry

If you change the properties of a web hook (for example the callback_uri) before the next retry then the new callback_uri will be used on the next retry.

After 5 Failures

After 5 consecutive failures the user that created the web hook will be emailed notifying them of the failures. This only happens in the event of 5 consecutive failures though, so if the fail counter is reset because a callback is successfully processed then no email will be sent.

After 100 Failures

After 100 consecutive failures the web hook will stop processing retries, and thus will only be attempting to perform callbacks on new events.

After 1000 Failures

After 1000 consecutive failures the web hook will automatically delete itself as it considers your site to be permanently down.

^ Back to Top ^