What this does
The moment a customer pays for one of your products, bookto sends the order details to every active webhook you have set up. This happens in real time, automatically — you don't have to do anything. You can use it to add buyers to your mailing list, log sales in a spreadsheet, send yourself a notification, or anything else your tools support.
Two keys, two purposes
On the Integrations page (in your dashboard), open the API key & webhooks card. It shows two different keys. They do opposite things — here's the difference in plain terms.
API key bk_… — incoming
You only need this if you connect through Zapier. You paste this key into Zapier so that Zapier is allowed to sign in to your bookto account. It is shown only once, right after you generate it — after that it can't be read again, so store it somewhere safe. In the API key & webhooks card you can Regenerate the key (replaces it — the old one stops working immediately) or Revoke it (disables it entirely).
Signing secret — outgoing
This is created automatically for you. bookto uses it to "sign" every webhook it sends, so the receiver can confirm the message genuinely came from bookto and wasn't faked by someone else. You only need to look at this if you're building that check into your own server. In the API key & webhooks card, use Reveal to see it while you build your verification, or Regenerate to roll it (any server that verifies signatures will need the new value). If you connect via Zapier or just don't verify the signature, you can ignore it.
Two ways to connect
1. Your own webhook URL
If you have a URL that can receive data (your own server, or a tool like Make or n8n), paste it under Webhooks and click Add. That's it — no API key needed. bookto will start POSTing every paid order to that URL.
2. Through Zapier
Generate an API key on the Integrations page and paste it into the bookto integration inside Zapier. Zapier then handles the webhook for you, and it will appear in your Webhooks list as "managed via Zapier". From there you can connect bookto to thousands of apps without writing any code.
Verifying the signature (for developers)
If you build your own server to receive webhooks, you can check that each request really came from bookto. Every POST includes these headers:
X-Bookto-Event— the event name, alwaysorder.paidX-Bookto-Timestamp— the time the webhook was sent, in unix secondsX-Bookto-Signature— the signature, in the formsha256=<hex>
To verify: compute HMAC-SHA256(signing_secret, "<timestamp>.<raw JSON body>") and compare it to the signature header. They should match exactly. Use the raw, unparsed request body — not a re-stringified version.
import crypto from 'crypto'
// "signingSecret" is the value from your Integrations page.
// "rawBody" is the exact, unparsed request body (a string).
function isFromBookto(req, rawBody, signingSecret) {
const timestamp = req.headers['x-bookto-timestamp']
const signature = req.headers['x-bookto-signature'] // "sha256=<hex>"
const expected =
'sha256=' +
crypto
.createHmac('sha256', signingSecret)
.update(timestamp + '.' + rawBody)
.digest('hex')
return signature === expected
}
What's in the payload
Every webhook sends the same JSON shape, so you can rely on it. Here's an example of what you'll receive:
{
"event": "order.paid",
"payment_provider": "mollie",
"order_id": "…",
"order_number": "ORD-…",
"status": "paid",
"created_at": "…",
"paid_at": "…",
"amount": {
"total_incl": 1.21,
"excl_vat": 1,
"vat": 0.21,
"vat_rate": 21,
"currency": "EUR"
},
"vat_treatment": "standard",
"product": { "name": "…", "description": "…" },
"buyer": {
"first_name": "…",
"last_name": "…",
"email": "…",
"company": "…",
"vat_number": "…",
"peppol_id": "…",
"address": "…",
"address2": "…",
"postal_code": "…",
"city": "…",
"country": "BE",
"match_ref": "…"
},
"custom_fields": [ { "label": "…", "value": "…" } ],
"seller": { "id": "…", "entity": null },
"is_test_order": false
}
The payload carries everything an invoice or bookkeeping tool needs: the buyer's full address, vat_number and peppol_id, the product description (not just the name), the VAT figures, and any custom_fields the buyer filled in at checkout. It is plain JSON, so any automation platform — Zapier, Make, n8n, or your own script — reads the exact same shape.
One customer, not a duplicate every time
When a returning buyer orders again, you want your accounting tool to reuse their existing contact, not create a second one. bookto does not merge contacts for you (we never want to accidentally merge two different people) — instead every payload includes a stable key, buyer.match_ref, that your scenario uses to find-or-create the contact. It is the buyer's VAT number when present, otherwise their peppol id, otherwise their email — normalised so it stays the same across orders.
The pattern (Zapier or Make)
- Trigger — "New paid order" (Zapier) or a custom webhook (Make / n8n), pointed at the URL from your Webhooks list.
- Search — "Find Customer/Contact" in your accounting app, searching on
buyer.match_ref(orbuyer.vat_number/buyer.emailif your app searches on those). - Create if not found — most apps have a "Find or create" step; otherwise add a "Create Customer" step that only runs when the search came back empty. Map name, email, address,
vat_numberandpeppol_id. - Create the invoice/order — use the matched (or newly created) customer, the product
name+description, theamountfigures, and thevat_treatment. Addcustom_fieldsas a note if your buyers fill them in.
Tip: match on the VAT number first — it is unique to a business, so it is the safest key for B2B. Falling back to email is fine for private buyers, but two different people could in theory share a mailbox, so prefer VAT where you have it.
Testing safely
A payment made in test mode also sends a webhook, marked with "is_test_order": true. That lets you try the whole flow without taking a real payment. A handy trick: paste a webhook.site URL into your Webhooks list to see exactly what bookto sends.
No duplicate notifications
Each paid order is delivered to your webhook only once, even if the payment provider repeats its own notification behind the scenes. You won't get the same order twice.