Skip to main content
Webhooks let Invoice AI push event notifications to your server in real time. Instead of polling the API to check whether an invoice has been paid or viewed, you register an HTTPS endpoint and Invoice AI calls it whenever a matching event occurs. Common use cases include:
  • Triggering an accounting entry when an invoice is marked paid.
  • Sending a Slack message when an invoice email bounces.
  • Updating a CRM when a client views or downloads an invoice.
  • Kicking off a fulfillment workflow when a finalized invoice is created.
To manage webhook endpoints, go to Settings → Webhooks, or use the API (POST /api/v1/webhook-endpoints) with a key that carries the webhooks:manage scope.

Creating a webhook endpoint

1

Open Webhooks settings

Go to Settings → Webhooks and click Add endpoint.
2

Enter your endpoint URL

Enter the full HTTPS URL of your receiver. The URL must use https:// — plain HTTP is not accepted.
3

Select events

Choose the specific events you want delivered to this endpoint, or select All events to receive everything. Subscribing only to the events you need reduces noise and processing load on your server.
4

Save and copy your signing secret

Click Create. Invoice AI displays the signing secret (whsec_…) once. Copy it immediately and store it securely — you will need it to verify incoming webhook signatures. You cannot retrieve it again.
The signing secret is shown only at creation time. If you navigate away without saving it, delete the endpoint and create a new one. Invoice AI cannot re-display a webhook secret.

Available events

Invoice AI fires the following events. Subscribe to individual events or to all of them.
Subscribe to invoice.email_failed so you can proactively follow up with clients when an automated send doesn’t reach them — this event is easy to miss without notifications.

Webhook payload structure

Every delivery is an HTTP POST request to your endpoint with a JSON body in this shape:
The data.object field contains the full invoice object at the time the event was fired.

Example: invoice.paid


Delivery headers

Every webhook delivery includes these HTTP headers: Invoice AI uses the Standard Webhooks signing scheme. The signature covers the delivery ID, timestamp, and body together — binding all three prevents replay attacks.

Verifying signatures

You must verify the webhook-signature header on every incoming request before processing it. Skipping this step means your endpoint will process requests from anyone who discovers its URL.

How signing works

Invoice AI computes the signature over the string {webhook-id}.{webhook-timestamp}.{raw-body} using HMAC-SHA256 with your endpoint’s signing secret (base64-decoded from the whsec_ prefix). The result is base64-encoded and prefixed with v1,. Replay protection: The timestamp is included in the signed string and Invoice AI rejects any delivery attempt your receiver flags as having a timestamp more than 5 minutes in the past or future. Always validate the timestamp as part of signature verification.

Node.js verification example

Always use a constant-time comparison (crypto.timingSafeEqual) when comparing signatures. A plain === leaks timing information that could allow an attacker to forge a valid signature character by character.

Python verification example

Express.js integration

Read the raw request body before any JSON-parsing middleware touches it. JSON parsers may reformat the body (different key ordering, whitespace), which changes the byte sequence and breaks the signature check. In Express, use express.raw({ type: 'application/json' }) on the webhook route instead of express.json().

Delivery and retries

Invoice AI delivers each event as a single HTTP POST. Your endpoint must respond with a 2xx status code within the timeout window to acknowledge successful receipt. If your endpoint returns a non-2xx status code or times out, Invoice AI retries the delivery with exponential back-off. Each retry carries the same webhook-id header — use this to deduplicate events safely in your receiver.

Deleting an endpoint

To stop receiving deliveries, go to Settings → Webhooks, find the endpoint in the list, and click Delete. Deletion is immediate. Any in-flight deliveries may still arrive for a few seconds after deletion.

Frequently asked questions

Yes. When creating an endpoint, choose All events instead of selecting individual event types. Your endpoint will receive every event Invoice AI fires, now and in the future.
You cannot retrieve the signing secret after the creation dialog is closed. Delete the endpoint from Settings → Webhooks and create a new one. Update the secret in your receiver’s environment at the same time.
Yes. You can create as many endpoints as you need. Each has its own URL, signing secret, and event subscriptions. Invoice AI delivers to all matching endpoints independently.
Use the webhook-id header as an idempotency key. Store processed IDs in your database with a unique constraint, or check before processing. If you see an ID you have already handled, return 200 without re-processing.
Yes. Send a POST to /api/v1/webhook-endpoints with a key that has the webhooks:manage scope. The response includes the signing secret — treat it the same way as if you created the endpoint in the UI. It will not be returned again.
The most common cause is that a JSON-parsing middleware reformatted the body before your signature check ran. Ensure you compute the signature over the raw, unmodified request body bytes. Also confirm you are reading webhook-id and webhook-timestamp as exact strings — do not cast the timestamp to a number before building the signed string.