Webhook sync
Send values one by one or in batch; exponential backoff, an offline queue, and an optional header.
Webhook sync is how QCR Scanner pushes the values you collect to your own server, an automation tool, or a Cloudflare Worker in real time. You define a webhook URL, and the app POSTs a JSON body to it for every value added to a list — or for the whole list, when you choose to. If the connection drops, requests are held in an offline queue and sent automatically once you are back online, and transient failures are retried with exponential backoff. The result is that your scanned data shows up in another system without ever putting the phone down.
Configuring the webhook
You reach the webhook settings from the app’s sync section. There are two fields:
- Webhook URL — The
https://address the requests are sent to. This can be any endpoint that can receive and process the body: your own API, an automation service, or a Cloudflare Worker. - Authorization header (optional) — If you fill it in, it is attached to every request as an
Authorizationheader, exactly as you typed it. This is handy for protecting your endpoint with a token or key. Leave it empty and no authorization header is sent.
The request body is always JSON, sent with a Content-Type: application/json header.
Tip: Enter the URL as an address that begins with
https://. Write the Authorization header in whatever form your endpoint expects (for exampleBearer ...or a plain key); the app passes the value through unchanged.
Testing the connection
After saving the URL, use Test connection to confirm you can reach your endpoint. This sends a single POST with a small JSON body:
{ "action": "ping" }
If your endpoint replies with a 2xx status, the test is considered successful. When you write a Worker or server, recognizing the ping action early and returning a quick 200 is the easiest way to validate your setup without sending any real data.
One by one or in batch?
You can send values in two ways.
One by one (auto-sync)
With auto-sync on, a single POST is sent the instant each new value is added to the list. This is ideal when you want to watch the data flow in real time during scanning — every validated value reaches your endpoint the moment it is added.
Batch (“Send all”)
With Send all, you send every item in the active list in one request. This suits the case where you collected a list offline and want to push it all at once afterwards, or where you keep auto-sync off and only send when you are done.
| Method | When | Body |
|---|---|---|
| One by one (auto-sync) | Instantly, as each value is added | A single item (add) |
| Batch (Send all) | When you trigger it, the whole list | An array of items (batch) |
Body format
Both methods use a consistent JSON structure; the action field tells the receiver what kind of request it is.
Single item (add)
In auto-sync, a single added value is sent like this:
{
"action": "add",
"listName": "Counters",
"item": {
"value": "AB-1234",
"isQR": false,
"source": "ocr",
"createdAt": "2026-06-21T10:15:00.000Z",
"isSeparator": false
},
"timestamp": "2026-06-21T10:15:00.000Z"
}
What the fields mean:
listName— The name of the list the value belongs to.item.value— The scanned or voice-entered value itself.item.isQR— Whether the value came from a QR code (true) or another source such as OCR/voice (false).item.source— Where the value came from (for exampleocr).item.createdAt— When the item was created (ISO 8601).item.isSeparator— Whether the item is a separator (such as a date or heading) or a normal value.timestamp— When the request was sent.
Batch (batch)
When Send all is triggered, the action becomes batch and all items are carried in an array, alongside a count:
{
"action": "batch",
"listName": "Counters",
"count": 2,
"items": [
{
"value": "AB-1234",
"isQR": false,
"source": "ocr",
"createdAt": "2026-06-21T10:15:00.000Z",
"isSeparator": false
},
{
"value": "CD-5678",
"isQR": true,
"source": "qr",
"createdAt": "2026-06-21T10:16:30.000Z",
"isSeparator": false
}
],
"timestamp": "2026-06-21T10:17:00.000Z"
}
Each item in the items array has the same fields as the item object in the single-item body. count gives the number of items in the array.
Exponential backoff
If a request fails with a transient error, the app does not drop it silently: it makes up to 3 attempts, doubling the wait between them. The wait intervals are 1s → 2s → 4s. A brief network blip or a momentary spike on your endpoint usually clears itself within this window; if all three attempts fail, the request is handed off to the offline queue.
Offline queue (outbox)
QCR Scanner is built for field conditions, so it keeps working without a connection.
- If there is no link at send time (or all attempts fail), the request is placed in an outbox queue.
- When the connection returns, the queued requests are sent automatically.
- The queue is also retried once more whenever the app comes back to the foreground.
This means the values you collect offline are never lost; they reach your endpoint in order as soon as the phone is online again.
Note: OCR and QR scanning already run entirely on-device, with no network. Webhook sync uses the network only to send the values you collect outward; your scanning ability keeps working fully even when you are offline.
Cloudflare Worker example
If you would rather not write the receiving side from scratch, a Cloudflare Worker is a practical option: it runs on the free tier, gives you a ready https endpoint, and can parse the ping, add, and batch actions in a few lines. Inside the Worker you look at the incoming action field, return a 200 immediately for ping, and write the body to your own storage or a table for add and batch. You can also validate the Authorization header in the Worker to protect your endpoint.
Tip: Whichever method you use, write your endpoint to recognize the
pingaction and return a2xx; that way the Test connection button gives you a meaningful result.
Webhook sync is part of QCR Scanner, made by ReviseTouch.
Next steps
- Lists — The multiple lists values are collected in, and list triggers.
- CSV export — Exporting and sharing the same data as a file.
- Validation rules — Deciding exactly which values make it into a list.
- FAQ — Quick answers about sync and other topics.