How to set up webhooks in SparkReceipt

Webhooks send your document data to a URL you choose whenever a document is created, updated, or deleted — so you can build automations with Zapier, Make, or your own systems.

ST
Written by SparkReceipt TeamUpdated Nov 10, 2026

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.

  1. In the SparkReceipt web app, open Account settings and select Integrations.
  2. Scroll to the Webhooks section.
  3. Click Add webhook.
  4. Enter the receiving URL and make sure Enabled is switched on.
  5. 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 created event 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 updated events.

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:

  • event is created, updated, or deleted; entity is always document today.
  • primary_category is one of expense, income, bank_statement, or document.
  • 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_conversion block that converts the document's total, subtotal and tax into your account's Home currency. source_currency is the document's currency, target_currency is the home currency, and date is the document date. rate is 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, rate is 1 and the converted amounts equal the originals. If no exchange rate is available, rate and the converted amounts are null. The converted amounts are not rounded, so round them to your currency's decimals if your system needs that.
  • Each line item also includes quantity and unit_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 (quantity is 1, unit_price is 0).
  • line_kind says what the line is: item, tax, tip, shipping, discount, refund, fee, adjustment or other. Discounts and refunds are negative amounts. An adjustment line covers the difference between the lines that were read and the total printed on the receipt.
  • For every line, line_subtotal plus line_tax is line_total. A receipt's printed sales tax arrives as its own tax line, with a line_subtotal of 0 and the tax in line_tax.
  • tax_rate is 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 example 8.25 or 0) while the sales tax itself sits on the tax line. It is null for a tax line 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_blocked field is true and its download URLs are empty.
  • In deleted events (and in the rare case where the document no longer exists when the webhook is sent), the payload contains document_id instead of the full document object.

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.