How to register a Webhook

Webhook Registration Endpoint Event subscription Test send

To receive webhooks, you register a receiving URL and the events you want on a developer app. You can do this in the developer portal or through the API. This article covers both, plus the test send, changing subscribed events, and pausing and deleting a webhook.

Before you start

  • An app registered in the developer portal. The developer API is available on the Starter plan and above
  • An https:// receiving URL reachable from the internet. localhost and private IP addresses cannot be registered
  • To register in the portal: you are the owner of the business account that owns the app
  • To register through the API: an access token bound to a business account (obtained through the business-account authorization flow). The webhook API does not require any particular scope

Portal or API

Operation Developer portal API
RegisterYes (secret is generated)Yes (give a secret or have one generated)
Whose events it receivesThe business account that owns the appThe business account the token is bound to
List and check statusYes (active/inactive, last delivered)Yes
Pause and resumeYesYes
Change subscribed eventsNoYes
Test sendNoYes
Delivery logNoYes (latest 50)
DeleteYesYes

The receiving URL cannot be changed later. To move to a new URL, register a new webhook and delete the old one.

Register in the portal

  • Open the app from the developer portal's app list (/en/organizations/{organizationId}/developer/apps)
  • In the Webhooks card, select Register
  • Enter the URL, tick the events you want, and select Register Webhook
  • The signing secret is shown at the top of the page. It is shown only this once, so copy it now and set it on your receiving server

The form lists every event name, but only receipt.created, order.created and order.updated are actually sent (see below).

Register through the API

curl -X POST https://receiptroller.io/api/v1/webhooks \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/rr-webhook",
    "eventTypes": ["receipt.created"],
    "secret": "{webhook_secret}"
  }'
Field Required Contents
urlYesAn absolute URL starting with https://. Not localhost, 127.0.0.1 or a private IP address
eventTypesYesAn array of event names to subscribe to (at least one). The name is eventTypes, not event_types
secretNoThe signing secret (16 to 64 characters). If omitted, a 32-character alphanumeric secret is generated

On success you get status 201 and the response below. secret appears only in this response; no endpoint returns it later.

{
  "id": "wh_xxxxxxxxxxxxxxxx",
  "clientId": "{client_id}",
  "organizationId": "{organizationId}",
  "url": "https://example.com/rr-webhook",
  "eventTypes": ["receipt.created"],
  "active": true,
  "createdAt": "2026-10-26T03:00:00.0000000Z",
  "lastDeliveredAt": null,
  "secret": "{webhook_secret}"
}

Registration errors

Status Message Cause
401(no body)The token is missing, expired or invalid
400organization_id not found in token.The token is not bound to a business account
400url is required.url is empty
400url must be a valid HTTPS address.Not an absolute https:// URL
400url must not point to localhost or private IP ranges.A local or private-IP URL
400event_types must contain at least one event.No events. You also get this if you name the field event_types
400Unknown event types: ...An event name that does not exist. The message goes on to list the valid names
400secret must be 16 to 64 characters, or omitted to have one generated.secret is too short or too long

Choosing events

Event Sent
receipt.createdWhen a new sale is saved for the first time
order.createdWhen an order is created
order.updatedWhen an order is edited or its status changes
receipt.updated, receipt.deleted, coupon.redeemed, coupon.expired, customer.visitedCan be registered, but are not sent

For what each event contains, see Webhook overview.

Test send

curl -X POST https://receiptroller.io/api/v1/webhooks/test/{webhook_id} \
  -H "Authorization: Bearer {access_token}"

One test.ping event is sent to the receiving URL and the result is returned.

{
  "webhookId": "wh_xxxxxxxxxxxxxxxx",
  "httpStatus": 200,
  "success": true,
  "deliveredAt": "2026-10-26T03:01:00.0000000Z"
}
  • The data in the body your URL receives is { "message": "This is a test ping from Receipt Roller." }. It is signed with the same secret as real events
  • The API answers 200 whenever the webhook exists. Whether it arrived is in success (your server returned 2xx) and httpStatus. An httpStatus of 0 means the connection itself failed
  • The test is sent regardless of subscribed events or the active flag, is not retried, and is not written to the delivery log
  • 404 means the ID is wrong or the webhook belongs to another app

Change, pause and delete

Change subscribed events, and pause or resume, with PATCH. Only the fields you send change, and eventTypes replaces the whole list.

curl -X PATCH https://receiptroller.io/api/v1/webhooks/{webhook_id} \
  -H "Authorization: Bearer {access_token}" \
  -H "Content-Type: application/json" \
  -d '{ "eventTypes": ["receipt.created", "order.created"], "active": true }'
  • "active": false pauses, "active": true resumes. The portal's pause and resume buttons do the same
  • Events that happen while paused are not held back and do not arrive after you resume
  • A webhook that fails four delivery attempts in a row is switched to active: false automatically. Resume it the same way once your server is fixed
  • Delete with DELETE /api/v1/webhooks/{webhook_id} (204 on success). Deleting cannot be undone
  • List registered webhooks with GET /api/v1/webhooks and fetch one with GET /api/v1/webhooks/{webhook_id}. Neither includes secret

Using several webhooks

  • One app can have several webhooks. Every webhook subscribed to an event receives it, all with the same X-RR-Delivery
  • To receive events from several business accounts, register with each business account's token
  • List, get, change, delete and test cover every webhook the app has registered (the list is the same whichever business account's token you call it with)

Checklist after registering

  • The receiving URL is https:// and reachable from outside
  • The secret is stored safely and set on the receiving server
  • The receiving server verifies the signature (Signature verification and security)
  • The test send returns success: true
  • Duplicates are dropped by X-RR-Delivery
  • Your server returns 2xx within 10 seconds

Related guides

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