Subscribe

POST https://api.bootic.net/v1/hub/{hub_id}/subscriptions

Create a webook subscription for a shop. Events matching the subscription criteria will be sent to target URL.

This endpoint is in early development and might change in the future.
Consider this a BETA feature.

HTTP POST

$ curl -XPOST \
  -H'Accept:application/json' \
  -H'Content-Type:application/json' \
  -H "Authorization: Bearer xxxx" -i \
  -d[REQUEST_BODY] \
  https://api.bootic.net/v1/hub/{shop.id}/subscriptions

Request body

{
  "topic": "orders.updated.placed",
  "url": "https://www.myapp.com/events",
  "notify_origin": true,
  "auth": {
    "type": "basic",
    "username": "foo",
    "password": "bar"
  }
}
topic
Event topic to subscribe to. See below for full list.
url
URL to POST event notifications to.
notify_origin
Whether or not to send webhooks to app that originated the request. Defaults to true.
auth (optional)
authentication credentials if your url is protected. Only “basic” supported currently.

Successful response

Status: 201 Created
Content-Type: application/json; charset=utf-8
Connection: keep-alive
ETag: "0728e2965bd03e20a7f1c33add2f8775"
Last-Modified: Fri, 20 Jun 2014 22:34:14 GMT
Cache-Control: must-revalidate, private, max-age=0
Date: Wed, 31 Jul 2013 21:11:52 GMT
X-OAuth-Scopes: admin
{
  "_class": [
    "hubSubscription"
  ],
  "_links": {
    "self": {
      "href": "https://api.bootic.net/v1/hub/123/subscriptions/222"
    },
    "history": {
      "href": "http://api.bootic.net/v1/hub/124/subscriptions/222/history{?page,per_page,sort,item_type,item_id,user_id,since,topic,created_on_gte,created_on_lte}"
    }
  },
  "id": 222,
  "status": "pending",
  "topic": "orders.updated.placed",
  "url": "https://www.myapp.com/events",
  "auth": {
    "type": "basic",
    "username": "foo",
    "password": "bar"
  },
  "error_count": 0,
  "last_error": "",
  "created_on": "2018-02-02T19:16:56Z",
  "updated_on": "2018-02-02T19:16:56Z"
}
status
one of “pending”, “active”, “failed_activation”, “failed”, “disabled” (see “subscription verification below”)
topic
event topic subscribed to
url
URL to send event notifications
auth
authentication credentials
error_count
how many times this subscription has failed
last_error
last error message, if any
created_on
date this subscription was created
updated_on
date this subscription was last updated or failed

Invalid response

Status: 422 Unprocessable Entity
Content-Type: application/json; charset=utf-8
Connection: keep-alive
ETag: "0728e2965bd03e20a7f1c33add2f8775"
Last-Modified: Fri, 20 Jun 2014 22:34:14 GMT
Cache-Control: must-revalidate, private, max-age=0
Date: Wed, 31 Jul 2013 21:11:52 GMT
X-OAuth-Scopes: admin
{
  "_class": [
    "errors"
  ],
  "_embedded": {
    "errors": [
      {
        "field": "$.topic",
        "messages": [
          "is required"
        ]
      },
      {
        "field": "$.url",
        "messages": [
          "must be a valid URL"
        ]
      }
    ]
  }
}

Event topics

Event topics go from less to more specific, left to right. The first segment is always the “domain” or class of resources. Examples:

Subscriptions can rely on this to subscribe to the subset of events they care about, for example subscribing to orders.updated will receive notifications for orders.updated.placed, orders.updated.closed, etc but not orders.updated or orders.created.

Note that events for a single resource (ie a single order) are sequential and denote state changes in the lifecycle of the resource. A orders.updated.closed event might include changes to other attributes (ex. updated_on). Those changes are included in the changes property of the event payload.

Available event topics

Orders

topic item scope description
orders order order any order event
orders.created order order order was created
orders.created.checkout order order order was created in checkout state (via API)
orders.udpated order order order was updated in general
orders.updated.checkout order order order transitioned from cart to checkout
orders.updated.cancelled order order order was cancelled by buyer
orders.updated.promotion.applied order order a promotion was applied to order
orders.updated.contact.set order order contact information added to order
orders.updated.payments.setup order order payment method chosen
orders.updated.payments.cancelled order order payment cancelled by buyer
orders.updated.payments.rejected order order payment rejected by gateway
orders.updated.placed order order order was placed
orders.updated.closed order order order was paid or closed by administrator
orders.updated.invalidated order order order was invalidated by administrator
orders.updated.shipped order order order was shipped
orders.updated.delivered order order order was delivered
orders.deleted order order order was deleted by administrator

Products

topic item scope description
products product depends any product event
products.created product product a product was created
products.updated product depends a product was updated
products.deleted product product a product was deleted
products.updated.variants.created product variant a product variant was created
products.updated.variants.updated product variant a product variant was updated
products.updated.variants.deleted product variant a product variant was deleted
products.updated.assets.created product asset a product asset was created
products.updated.assets.deleted product asset a product asset was deleted

Scope

All events refer to one of the top-level entities in this API (product, order), but some events will refer specifically to sub-entities within one of those.
For example, products.updated.variants.created refers to a particular product (as denoted in its item_type and item_id properties, but its changes and item properties refer to a specific variant entity being created for that product.

Your code should check scope to know if the entity data included in the event refers to the top-level product or to a specific variant or asset within the product.

Subscription verification

When a subscription is first created, the API sends a POST request to the provided url including a X-Hook-Ping header with a random string.

POST https://www.myapp.com/events
Authorization: Basic etc...
X-Hook-Ping: ifueidehdiuhfrh4r4rkfjer

{
  "topic": "activation"
}

To activate the subscription, the consumer app must respond with a X-Hook-Pong header with the same value of the incoming X-Hook-Ping.

204 No Content
X-Hook-Pong: ifueidehdiuhfrh4r4rkfjer

If the response status is in the 200 range and X-Hook-Pong is valid, the subscription is activated. Otherwise its status is updated to failed_activation.

Subscription states

status description
pending subscription created, pending verification and activation
active subscription is verified and active
failed_activation activation failed (target URL rejected it or returned error)
failed subscription was disabled after 3 consecutive failed notifications
disabled subscription was purposely disabled, either via API or by returning 410 in last notification

Publishing notifications

When an order or product is updated, HTTP POST notifications will be sent to URLs of subscribers for the relevant topics.

A notification includes:

Example:

POST https://myapp.com/events
Authorization: Basic etc...

{
  "topic": "orders.updated",
  "created_on": "2017-09-10T00:00:00Z",
  "sequence": 1233,
  "info": "order updated",
  "item_type": "order",
  "item_id": 333,
  "changes": {
    status": ["pending", "closed"],
  },
  "user_id": 555,
  "user_name": "Joe Bloggs",
  "shop_id": 765,
  "shop_subdomain": "acme",
  "_embedded": {
    "item": {
     // Order entity here
     // https://developers.bootic.net/rels/order/
    }
  }
}

Error handling

Webhook URLs that incur in 3 consecutive errors when sending notifications will cause a subscription to be disabled.

Errors are defined as any response status that is not in the 200..299 range, or requests that take more than 10 seconds to respond.

URLs that respond with status 410 Gone will cause the subscription to be inmediatly disabled.

Disabled subscriptions can enter the verification/activation cycle again by re-issuing the subscribe request with the same parameters.

Consumers can list subscriptions to find out their current states.