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 in this event type 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
}
}
FieldDescription
exchange_idstring Exchange identifier you can use to get an exchange.
order_idstring Order identifier you can use to get an order.
fee_ratedecimal Fee rate deducted from cost.
pairstring Exchange pair in base/quote currency. Either btc/eur or btc/chf.
typestring Exchange type buy or sell.
costdecimal Cost of the exchange in quote currency eur or chf.
executed_onstring Exact date and time of the execution in ISO 8601.
amountdecimal Amount of the exchange in base currency btc.
ratedecimal Exchange rate in quote currency eur or chf.
feedecimal Fee in quote currency eur or chf.
actionnull Only available in exchange.interrupted event.
reasonnull Only available in exchange.refunded event.
payoutnull Only available in exchange.settled event.

Event exchange.interrupted

Please note that in this event type 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
}
}
FieldDescription
exchange_idstring Exchange identifier you can use to get an exchange.
order_idstring Order identifier you can use to get an order.
fee_ratedecimal Fee rate deducted from cost.
pairstring Exchange pair in base/quote currency. Either btc/eur or btc/chf.
typestring Exchange type buy or sell.
costdecimal Cost of the exchange in quote currency eur or chf.
executed_onnull Only available in exchange.executed and exchange.settled event.
amountdecimal Only available in exchange.executed and exchange.settled event.
ratedecimal Only available in exchange.executed and exchange.settled event.
feedecimal Only available in exchange.executed and exchange.settled event.
actionobject Action needed to uninterrupt this exchange.
reasonnull Only available in exchange.refunded event.
payoutnull Only available in exchange.settled event.

Interruption actions

The action needed to uninterrupt the exchange is provided in the action object:

{
"action": {
"code": "identification_required",
"identification_id": "7bf967b5-3d34-4cd6-936c-6631811401d2"
}
}

There is only one possible code available:

  • identification_required - In order to process this exchange a full identification is needed. An identification_id identifier is provided. Contact us to find out how you can start an identification with it.

Event exchange.refunded

Please note that in this event type 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
}
}
FieldDescription
exchange_idstring Exchange identifier you can use to get an exchange.
order_idstring Order identifier you can use to get an order.
fee_ratedecimal Fee rate deducted from cost.
pairstring Exchange pair in base/quote currency. Either btc/eur or btc/chf.
typestring Exchange type buy or sell.
costdecimal Cost of the exchange in quote currency eur or chf.
executed_onnull Only available in exchange.executed and exchange.settled event.
amountdecimal Only available in exchange.executed and exchange.settled event.
ratedecimal Only available in exchange.executed and exchange.settled event.
feedecimal Only available in exchange.executed and exchange.settled event.
actionnull Only available in exchange.interrupted event.
reasonobject Reason for the refund.
payoutnull Only available in exchange.settled event.

Refund reasons

The reason why an exchange is refunded is provided in the reason object:

{
"reason": {
"code": "threshold_exceeded"
}
}

These are the possible reason codes:

  • threshold_exceeded - A threshold was exceeded and the exchange could not be processed, e.g. due to lack of full identification.
  • order_inactive - The order was set to inactive and cannot be used unless activated again.
  • companies_unsupported - Payment arrived from a company bank account which is not yet supported.
  • country_unsupported - Payment arrived from a country which is not yet supported.
  • other_risk_detected - Some other risk was detected that prevents this exchange from being executed.
  • customer_requested - The customer requested a refund of their payment.
  • account_not_matching - Payment arrived from another person than the one associated with the order.

Event exchange.settled

Please note that in this event type 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
}
}
}
FieldDescription
exchange_idstring Exchange identifier you can use to get an exchange.
order_idstring Order identifier you can use to get an order.
fee_ratedecimal Fee rate deducted from cost.
pairstring Exchange pair in base/quote currency. Either btc/eur or btc/chf.
typestring Exchange type buy or sell.
costdecimal Cost of the exchange in quote currency eur or chf.
executed_onstring Exact date and time of the execution in ISO 8601.
amountdecimal Amount of the exchange in base currency btc.
ratedecimal Exchange rate in quote currency eur or chf.
feedecimal Fee in quote currency eur or chf.
actionnull Only available in exchange.interrupted event.
reasonnull Only available in exchange.refunded event.
payoutobject Payout details.

Settled payout

The payout details are provided in the payout object:

FieldDescription
txidstring Bitcoin transaction identifier.
outpointstring Index of the output inside of the Bitcoin transaction.
bitcoin_addressdecimal Bitcoin address paid out to.
derivation_pathstring Derivation path to the bitcoin_address paid out to. Only available if Order was created with extended_public_key.
block_heightinteger Index of the Bitcoin block in which the Bitcoin transaction was first confirmed in. null until first confirmation.
confirmationsinteger Number of confirmations the Bitcoin transaction has received. 0 when broadcast, 1 on first confirmation.
feedecimal Bitcoin network fee deducted from payout.
amountdecimal Effective payout amount with the fee already deducted.