Skip to main content

Webhook Endpoints

Webhook endpoints let Invoice AI push event notifications to your server in real time. When something significant happens — an invoice is paid, an email bounces, a client views an invoice — Invoice AI sends an HTTP POST to each registered endpoint that subscribes to that event type. Base URL: https://invoice.horizonpay.co/api/v1

Before you begin

  • Endpoint URLs must use HTTPS. Plain HTTP is rejected.
  • URLs that resolve to private, loopback, or link-local IP ranges are blocked (this includes cloud metadata addresses like 169.254.169.254). Redirects are never followed.
  • When you create an endpoint, the API returns a signing secret (whsec_…) exactly once. Store it securely in your environment variables — it cannot be retrieved again.
  • All deliveries are signed using the Standard Webhooks signature scheme. See Signature verification below.

The webhook endpoint object

When you create an endpoint, the response also includes a one-time "secret" field (e.g. "whsec_abc123..."). Subsequent reads and list calls never return the secret.
string
UUID for this webhook endpoint.
string
The HTTPS URL that receives event POST requests.
string[]
Array of subscribed event type strings. An empty array at creation time means all event types are delivered. After creation, the full expanded list of event types is returned so you can see exactly what will be delivered.
boolean
true when the endpoint is active and receiving deliveries. Set to false automatically when the endpoint exceeds the failure threshold.
string | null
ISO 8601 datetime at which the endpoint was automatically disabled after repeated delivery failures. null while active.
integer
Cumulative count of failed delivery attempts to this endpoint.
string
ISO 8601 datetime at which the endpoint was created.

Endpoints

List all registered webhook endpoints in your workspace, newest first.Required scope: webhooks:manage

Request

Response

Register a new webhook endpoint. The signing secret is returned in the response only once and cannot be retrieved again — store it immediately.Required scope: webhooks:manageOptionally send an Idempotency-Key header to safely retry this request.

Body parameters

string
required
The HTTPS URL that Invoice AI will POST events to. Must be publicly reachable and must not resolve to a private IP range.
string[]
Array of event type strings to subscribe to. Omit or pass [] to receive all current and future event types. See event types for the full list.

Request

Response 201 Created

The secret field appears only in this create response. Copy it now and store it in a secrets manager or environment variable. There is no way to retrieve it again — you would need to delete and re-create the endpoint to get a new secret.
Permanently delete a webhook endpoint. Deliveries in progress are not affected, but no new deliveries will be sent to this URL after deletion.Required scope: webhooks:manage
Deleting an endpoint that is already gone returns 404 Not Found rather than silently succeeding — this is intentional so you can detect stale IDs.

Request

Response 204 No Content

An empty body is returned on successful deletion.

Delivery behavior

Request format

Every delivery is an HTTP POST with Content-Type: application/json. The body is a webhook event payload.

Signature headers

Each delivery carries three headers used for verification: The signature scheme follows the Standard Webhooks specification. The signed string is:
The HMAC key is the base64url-decoded payload of your whsec_… secret.

Retry schedule

If your endpoint returns a non-2xx status code, times out (10 seconds), or is unreachable, Invoice AI retries on this schedule: After all 6 retries are exhausted, the delivery is abandoned. Repeated failures increment failure_count and may disable the endpoint automatically.

Responding to deliveries

Return any 2xx status code to acknowledge receipt. Invoice AI reads only the status code — the response body is ignored (beyond logging up to 500 characters on failure). Respond quickly (within 10 seconds). If your processing logic takes longer, acknowledge receipt immediately and process the payload asynchronously. Redirects (3xx) are never followed and are treated as failures.

Deduplication

The webhook-id header is stable across retry attempts. If your endpoint processes an event and then crashes before returning 200, you may receive the same event again. Use webhook-id as an idempotency key to deduplicate.

Signature verification

Verify every incoming delivery before processing it.
Always use a constant-time comparison (timingSafeEqual) when checking signatures. A standard string equality check (===) is vulnerable to timing attacks that can allow an attacker to forge a valid signature.

Error responses