Webhook overview

Webhook Events API receipt.created order.created

A webhook is how ReceiptRoller tells your server, with an HTTPS POST to a URL you register, that a sale or an order has happened in a business account. This article covers which events are actually sent, what the request looks like, what delivery does and does not guarantee, and when to use the API instead.

How it works

  • You register webhooks per developer app, giving a receiving URL and the events you want. One app can have several webhooks
  • A webhook belongs to one business account and receives only the events that happen in that business account
  • When an event happens, ReceiptRoller POSTs signed JSON to every active webhook subscribed to it
  • A 2xx response within 10 seconds is a success. A failure is retried after 1 minute, 10 minutes and 1 hour; if all four attempts fail, the webhook is switched off
  • The developer API is available on the Starter plan and above

Events that are sent

Event Sent when What data holds
receipt.created A store's sale is saved in ReceiptRoller for the first time (connected POS, payment terminal or CSV import). Once per sale: a resend, re-sync or re-import of the same sale is not announced again. Not sent for a deleted sale A summary of the sale (terminal_id, transaction_id, store_id, receipt_number, issued_at, status, total_amount, tax_amount, currency and more). No customer identifiers
order.created An order is created in order management The whole order (order_id, order_number, status, total_amount, the orderer's name, contact details and shipping address, items_json and more)
order.updated An order is edited, or its status changes through confirm, start processing, cancel or hand-over at a store POS For an edit, the whole order. For a status change, only order_id, organization_id and status (plus linked_pos_terminal_id and linked_pos_transaction_id for a POS hand-over)
test.ping Only when you call the test endpoint { "message": "This is a test ping from Receipt Roller." }

receipt.updated, receipt.deleted, coupon.redeemed, coupon.expired and customer.visited can also be chosen at registration, but they are not sent. Subscribing to them delivers nothing.

receipt.created is not filtered by the sale's status. A transaction saved for the first time as voided (Voided) or refunded (Refunded) is sent too, so check status on your side if you only want sales.

The request you receive

  • The method is POST and the body is UTF-8 JSON (Content-Type: application/json)
  • Every key in the body is snake_case
Header Contents
X-RR-Signature sha256= followed by the lower-case hex HMAC-SHA256 of the raw body, keyed with the webhook's secret
X-RR-Event The event name, e.g. receipt.created
X-RR-Delivery The event's ID. The same value as the body's id, and unchanged on retries

The body looks like this.

{
  "id": "evt_1a2b3c4d5e6f",
  "event": "receipt.created",
  "timestamp": "2026-10-26T03:15:43.1234567Z",
  "organization_id": "{organizationId}",
  "data": { ... }
}
  • id: the event ID (evt_ plus 12 hex characters). Use it to drop duplicates
  • event: the event name
  • timestamp: when ReceiptRoller sent the event out (UTC). Retries carry the same value
  • organization_id: the ID of the business account the event happened in
  • data: the event's contents (see the table above)

What delivery guarantees, and what it does not

  • An event can arrive more than once. It is retried when, for example, your server finished processing but did not manage to return 2xx. Drop duplicates by X-RR-Delivery (the body's id)
  • Order is not guaranteed. Each event is sent on its own and retries arrive later. An order.updated can arrive before its order.created
  • An event can be lost. Pending retries are held on a ReceiptRoller server, not saved to a queue. If that server restarts while a retry is waiting, the remaining retries do not happen. Events that occur while a webhook is switched off are not held back and are never sent later
  • There is no way to resend a past event by hand

So for an integration that must not miss anything, treat the webhook as a trigger and reconcile against the API on a schedule.

Webhook or API

What you want Use
Know about a new sale or order straight away Webhook
List past sales, or aggregate daily API (Transactions API)
Also need line items or member details Learn of the sale by webhook, then fetch it from the API using terminal_id and transaction_id
Know about corrected or deleted sales, coupon use or visits API. These events are not sent yet
Make sure nothing is missed Both: receive by webhook, reconcile with the API on a schedule

Related guides

Published: 2026-04-27 Updated: 2026-10-26