REST API v1

Webhooks

The Pocket webhooks allow you to react to various events in real-time:

  • Incoming purchases
  • Payouts
  • Identification requests
  • Refunds

You'll receive these events for all orders you've created through the Pocket REST API v1.

Registration

Soon you'll be able to register your webhook endpoints by yourself. Until then, please contact us.

Webhook request

For each event you'll receive an HTTP request to every of your registered webhook endpoints.

The basic structure of these requests is as follows:

POST /webhook
Content-Type: application/json
User-Agent: Pocket-Webhook/1.0
X-Signature-256: 89cc7396704998f25bd0019bdc2ec30de78ff0c89add39685b30df608ba2a8d6
X-Correlation-Id: 7320abc0-c88f-4d72-b72c-deae658782e2
X-Retry-Count: 0
{
"event": "event.action",
"payload": {
"some": "payload"
}
}

Signature validation

It is highly recommended that you validate the X-Signature-256 header attached to every webhook request. It's the only way to confirm that the request originated from Pocket and thus its payload can be trusted.

The signature is created by calculating the HMAC-SHA256 of the request body using a shared secret key. You're free to choose a shared secret key during registration of your webhook endpoint.

The X-Signature-256 value is always prefixed with sha256=, so please prepend this prefix to your calculated signature before comparing.

See bitkipi/sig-tools for an example on how to calculate the signature.

Correlation header

We recommend you to log the X-Correlation-Id header while processing a webhook request. In case of an issue, this information allows us to precisely track the request up to its origin.

Error handling

Webhook delivieries are automatically retried on failure. Anything other than HTTP 2xx is considered a failed delivery and will lead to a retry in 5 minutes. That delay is doubled on every further attempt.

In the future you'll be able to list and resend single webhook events, for example after scheduled maintenance of your system. Until then, please contact us.

Event Types

The request payload depends on the type of event being sent. These are the possible event types:

Event TypeDescription
exchange.executedThe exchange was executed. Includes all execution details but no payout information yet.
exchange.interruptedThe exchange was not executed and was interrupted. An available action is attached.
exchange.refundedThe exchange was refunded automatically or after exchange.interrupted. A reason is attached.
exchange.settledThe exchange was settled. Includes all execution details and all payout information. Called once while unconfirmed and another time with 6 confirmations. Called again if transaction was replaced.

Event exchange.executed

Please note that the action, reason and payout fields are always null.

{
"event": "exchange.executed",
"payload": {
"exchange_id": "a2d75998-5ee5-4501-a4cf-4e3788732b7a",
"order_id": "64decab6-4129-4fe7-9f6e-1db68283f5ce",
"fee_rate": 0.015,
"pair": "btc/chf",
"type": "buy",
"cost": 100.00,
"executed_on": "2021-09-15T14:35:10.122Z",
"amount": 0.00197000,
"rate": 50000.00,
"fee": 1.50,
"action": null,
"reason": null,
"payout": null
}
}

Event exchange.interrupted

Please note that all execution details are empty, including reason and payout, but the action field is set.

{
"event": "exchange.interrupted",
"payload": {
"exchange_id": "a2d75998-5ee5-4501-a4cf-4e3788732b7a",
"order_id": "64decab6-4129-4fe7-9f6e-1db68283f5ce",
"fee_rate": 0.015,
"pair": "btc/chf",
"type": "buy",
"cost": 100.00,
"executed_on": null,
"amount": null,
"rate": null,
"fee": null,
"action": {
"code": "identification_required",
"identification_id": "7bf967b5-3d34-4cd6-936c-6631811401d2"
},
"reason": null,
"payout": null
}
}
Action: identification_required
{
"action": {
"code": "identification_required",
"identification_id": "7bf967b5-3d34-4cd6-936c-6631811401d2"
}
}

Event exchange.refunded

Please note that all execution details are empty, including action and payout, but the reason field is set.

{
"event": "exchange.refunded",
"payload": {
"exchange_id": "a2d75998-5ee5-4501-a4cf-4e3788732b7a",
"order_id": "64decab6-4129-4fe7-9f6e-1db68283f5ce",
"fee_rate": 0.015,
"pair": "btc/chf",
"type": "buy",
"cost": 100.00,
"executed_on": null,
"amount": null,
"rate": null,
"fee": null,
"action": null,
"reason": {
"code": "threshold_exceeded"
},
"payout": null
}
}
Reason: threshold_exceeded
{
"reason": {
"code": "threshold_exceeded"
}
}

Event exchange.settled

Please note that the action and reason fields are always null.

{
"event": "exchange.settled",
"payload": {
"exchange_id": "a2d75998-5ee5-4501-a4cf-4e3788732b7a",
"order_id": "64decab6-4129-4fe7-9f6e-1db68283f5ce",
"fee_rate": 0.015,
"pair": "btc/chf",
"type": "buy",
"cost": 100.00,
"executed_on": "2021-09-15T14:35:10.122Z",
"amount": 0.00197000,
"rate": 50000.00,
"fee": 1.50,
"action": null,
"reason": null,
"payout": {
"txid": "c01c7a0fd270aa3876119098c0e2d51687a795efab99787e214d8a93ab9f8342",
"outpoint": 1,
"bitcoin_address": "bc1q5vvayqt3n4alhjaxy6ql4w2fs6r0y83rmvh3tg",
"derivation_path": null,
"block_height": null,
"confirmations": 0,
"fee": 0.00000190,
"amount": 0.0019681
}
}
}