Events and webhooks
Each event fires once, at the moment the Collects app shows the change, and only to a connection whose person can see that change in the app. An event carries ids only: { id, type, created_at, data }, where data holds invoice_id, debtor_id, resolution_id or task_id. Fetch the details with your own token (GET /invoices/{id}, GET /debtors/{id}, GET /tasks/{id}), so your role, an erasure and the retention period apply when you read them.
| Event | Fires |
|---|---|
invoice.resolved | When a resolution started through the API closes: by a promise to pay, a payment plan, a dispute or the end of the reminder sequence. |
invoice.collected | Once per invoice, when Collects records it as collected: paid, in full or in part, on a day after Collects first acted on it. resolution_id is empty for an invoice with no resolution. |
invoice.payment_received | Sent for each payment Xero records against an invoice, in full or in part, when the invoice shows “Payment received”. |
invoice.dispute_opened | Sent when a dispute is logged on an invoice and reminders pause, as the invoice and the Disputes page show it. |
invoice.dispute_resolved | Sent once per dispute, when it is resolved and the invoice shows “Dispute resolved”. |
invoice.reply_received | Sent when a reply from the customer is matched to an invoice and shows on it as a reply received. |
invoice.reminders_paused | Sent when reminders are paused on an invoice and the invoice shows it. |
invoice.reminders_resumed | Sent when reminders resume on an invoice and the invoice shows it. |
invoice.promise_to_pay_recorded | Sent when a promise to pay, or a payment plan, is recorded on an invoice. |
invoice.promise_to_pay_kept | Sent when an invoice shows “Promise to pay kept”: the payment plan was paid as promised. |
invoice.promise_to_pay_missed | Sent when a promise to pay is missed, or marked missed, and the invoice shows it. |
invoice.email_sent | Sent when Collects sends an email to the customer about an invoice and the invoice shows it as sent. |
invoice.email_bounced | Sent when an email Collects sent about an invoice bounces and the invoice shows it as “Sent — bounced”. |
invoice.overdue | Sent once when an open invoice passes its due date (the UK date) and the invoice starts to show days overdue. |
task.created | Sent when a task is added to the Workbench. |
debtor.reminders_paused | Sent when reminders are paused for a customer (“Pause this customer”), across all of their invoices. |
debtor.reminders_resumed | Sent when reminders resume for a customer who was paused, across all of their invoices. |
Polling
GET /events lists the events your connection can see, newest first, for 400 days. Filter with type (repeat it for several) and page with the next_cursor it returns.
Webhooks
Subscribe with POST /webhooks (several events) or POST /webhooks/events/{event_type} (one). The answer carries the subscription's signing secret once: store it. A subscription belongs to the connection that made it and ends with it. GET /webhooks lists them and DELETE /webhooks/{subscription_id} removes one. A subscription is pinned to the API version of the request that created it (see Versioning).
Each delivery is a POST of the event, signed the Standard Webhooks way:
webhook-id: the event id, the same on every retry;webhook-timestamp: Unix seconds;webhook-signature:v1,then the base64 HMAC-SHA256 of{webhook-id}.{webhook-timestamp}.{body}, keyed with the secret's bytes afterwhsec_(base64-decoded);Collects-Version: the version the subscription is pinned to.
Check the signature against the raw body and refuse a timestamp more than five minutes old. Answer with any 2xx. A 5xx, a timeout or a network error is retried after 1, 5 and 30 minutes; any other 4xx ends that delivery; 410 Gone ends the subscription.