What webhooks do
A webhook lets SparkReceipt push your document data to your own systems automatically. Whenever a document — an expense, income document, or bank statement — is created, updated, or deleted in your account, SparkReceipt sends an HTTP POST request with a JSON payload to a URL you configure. The payload contains the document's extracted data (vendor, date, totals, taxes, categories, tags, line items, and more) plus download links to the original files.
This is the building block for custom integrations: route new receipts into your own database, trigger a Zapier or Make scenario, copy files to cloud storage, or notify your team's chat when a large invoice arrives.
Setting up a webhook
Webhook settings are available to account owners, admins, and users with the Accountant role.
- In the SparkReceipt web app, open Account settings and select Integrations.
- Scroll to the Webhooks section.
- Click Add webhook.
- Enter the receiving URL and make sure Enabled is switched on.
- Save the webhook. Its status on the Integrations page changes to Active.
A few requirements for the URL:
- It must be a valid, publicly reachable HTTP or HTTPS address. URLs that point to private or internal network addresses are rejected for security reasons.
- Your endpoint should respond with a 2xx status code (for example
200 OK) to acknowledge the delivery. Any other response is recorded as a failed delivery.
Each SparkReceipt account supports one webhook. If you need to fan events out to several systems, point the webhook at an automation tool (like Zapier or Make) or a relay endpoint of your own and distribute from there.
When the webhook fires
The webhook fires on three events: created, updated, and deleted. Every document in the account triggers it — there is currently no way to subscribe to only a subset of events or document types.
Deliveries are delayed and batched rather than sent instantly. By default, SparkReceipt waits about 5 minutes after an event before calling your endpoint, and all changes to the same document within that window are combined into a single call (the settings page shows the current delay for your account):
- If a document is created and then edited right away — for example, you fix the vendor name just after scanning — you receive one
createdevent containing the final data. - If a document is created and deleted within the window, the events cancel out and nothing is sent.
- Separate changes to the same document outside the window arrive as separate
updatedevents.
This batching means your automation doesn't get flooded with intermediate states while a document is still being processed and reviewed.
The payload
Each delivery is a POST request with Content-Type: application/json. The top level of the payload identifies the account, the event, and the entity; created and updated events include the full document object, while deleted events include only the document_id.
Here is an abbreviated example of a created event for an expense:
{
"organization_id": "7b54b45b-a813-41e9-ad67-27d504382072",
"organization_name": "Acme Corp",
"task_id": "59dc4c27-389a-42a9-a42b-f49745274dad",
"entity": "document",
"event": "created",
"task_created_at": "2026-07-16T12:34:00Z",
"task_sent_at": "2026-07-16T12:39:00Z",
"document": {
"id": "3a964309-b83d-495c-8f4f-84d395947e7f",
"name": "Invoice #1001",
"date": "2026-06-30",
"description": "Consulting services",
"currency_code": "USD",
"reference_number": "INV-1001",
"raw_text": "Text extracted from the document...",
"review_status": "reviewed",
"input_source": "inbound_email",
"user": {
"id": "3328431d-3bd6-418b-9f70-634480d9739a",
"email": "user@example.com",
"name": "Jane Doe",
"role": "admin",
"status": "active"
},
"trashed": false,
"files": [
{
"id": "319e266d-0ba9-4d15-8587-5769d5d20ef5",
"malware_blocked": false,
"preview_url": "https://...",
"url": "https://...",
"filename": "invoice.pdf",
"content_type": "application/pdf"
}
],
"primary_category": "expense",
"secondary_category": {
"id": "c7b48b80-401a-499c-938a-64610dea8443",
"title": "Consulting"
},
"tags": ["urgent", "finance"],
"total": 1500.0,
"subtotal": 1400.0,
"tax": 100.0,
"tax_mode": "exclusive",
"document_value_lines": [
{
"id": "a1d0f0c2-5b7e-4f61-9d3c-0e2b8f6c4a11",
"name": "Consulting, 2 days",
"line_kind": "item",
"line_total": 1500.0,
"line_subtotal": 1400.0,
"line_tax": 100.0,
"tax_rate": 7.14,
"quantity": 2.0,
"unit_price": 700.0
}
],
"payment_method": {
"id": "5c1591f6-1424-4f0d-bae6-0ad1492f8283",
"name": "Credit Card",
"type": "card"
},
"currency_conversion": {
"rate": 0.92,
"date": "2026-06-30",
"source_currency": "USD",
"target_currency": "EUR",
"converted_total": 1380.0,
"converted_subtotal": 1288.0,
"converted_tax": 92.0
},
"created_at": "2026-07-16T12:30:00Z",
"updated_at": "2026-07-16T12:34:00Z"
}
}
Notes on specific fields:
eventiscreated,updated, ordeleted;entityis alwaysdocumenttoday.primary_categoryis one ofexpense,income,bank_statement, ordocument.- For expenses and income, the payload includes the money fields shown above (
total,subtotal,tax, line items) in the document's own currency (currency_code). - Expenses and income always include a
currency_conversionblock that converts the document's total, subtotal and tax into your account's Home currency.source_currencyis the document's currency,target_currencyis the home currency, anddateis the document date.rateis the exchange rate on that date, or the rate entered on the document if someone set one. When the document is already in the home currency,rateis1and the converted amounts equal the originals. If no exchange rate is available,rateand the converted amounts arenull. The converted amounts are not rounded, so round them to your currency's decimals if your system needs that. - Each line item also includes
quantityandunit_price(display-only per-line metadata). Both are always present as numbers; when a per-line value was not captured they fall back to their defaults (quantityis1,unit_priceis0). line_kindsays what the line is:item,tax,tip,shipping,discount,refund,fee,adjustmentorother. Discounts and refunds are negative amounts. Anadjustmentline covers the difference between the lines that were read and the total printed on the receipt.- For every line,
line_subtotalplusline_taxisline_total. A receipt's printed sales tax arrives as its owntaxline, with aline_subtotalof0and the tax inline_tax. tax_rateis the line's own tax rate in percent. A line with both GST and PST adds the two rates together. On a US receipt an item shows whether it is taxable (for example8.25or0) while the sales tax itself sits on thetaxline. It isnullfor ataxline and for a line without a rate.- Documents also carry their AI Field values, integration publish status, and other metadata.
- If a file was blocked by malware scanning, its
malware_blockedfield istrueand its download URLs are empty. - In
deletedevents (and in the rare case where the document no longer exists when the webhook is sent), the payload containsdocument_idinstead of the fulldocumentobject.
Monitoring deliveries with the event log
Next to the webhook settings you'll find the Event log, which lists every webhook event with its queue time, event type, the document it concerns, delivery status, sent time, and the HTTP response code your endpoint returned.
What the Response code column means (and the old "N/A")
- A number is the HTTP status code your endpoint answered with. A code in the 200s means the delivery was accepted. Any other code, such as 404 or 500, means your endpoint refused it or failed.
- Pending means the event hasn't been delivered yet. It is still waiting for the batching window or is being sent.
- No response recorded means the delivery finished without an HTTP answer from your endpoint. Usually the request never got through, for example because the URL didn't resolve, the connection was refused or it timed out. It can also mean the event was stopped before anything was sent. Check that your endpoint is reachable, then use Restart on the event.
Older versions of the event log showed N/A in this column for both of the last two cases. If you see N/A, read the event's Status: a Queued event hasn't been sent yet, and a Failure or Complete event got no HTTP response.
From the log you can also re-send events:
- Send now delivers a queued event immediately instead of waiting for the batching window.
- Restart re-sends an event that already completed or failed. Failed deliveries are not retried automatically, so if your endpoint was down, use the event log to restart the missed events once it's back up. When restarting an already-successful event, make sure your automation can handle receiving the same event twice.
Using webhooks with Zapier or Make
You don't need to run your own server to use webhooks. Both Zapier and Make can receive them directly:
- In Zapier, create a Zap that starts with the Webhooks by Zapier trigger ("Catch Hook") and paste the generated URL into SparkReceipt as your webhook URL.
- In Make, add a Webhooks → Custom webhook module to a scenario and use its address the same way.
From there you can map the document fields to thousands of other apps — spreadsheets, cloud storage, accounting tools, or chat notifications.