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 HTTPPOST 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
GET /api/v1/webhook-endpoints — List endpoints
GET /api/v1/webhook-endpoints — List endpoints
POST /api/v1/webhook-endpoints — Create an endpoint
POST /api/v1/webhook-endpoints — Create an endpoint
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: Response
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
DELETE /api/v1/webhook-endpoints/:id — Delete an endpoint
DELETE /api/v1/webhook-endpoints/:id — Delete an endpoint
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: Response
An empty body is returned on successful deletion.
webhooks:manageDeleting 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 HTTPPOST 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:
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
Thewebhook-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.