Events and webhooks
ARC has several event surfaces for different audiences. For server-to-server change notifications, use outbound webhooks.
What exists today
| Surface | Direction | Authentication | Use |
|---|---|---|---|
| Outbound webhooks | ARC → your HTTPS endpoint | HMAC-SHA256 signature (X-ARC-Signature) with a per-endpoint secret. Endpoints are managed with a user JWT whose role holds the settings:webhooks:read, create, update or delete permission. | Signed notifications for orders, invoices, quotes and stock adjustments. Retried (6 attempts in total) and replayable while the delivery record is kept (30 days). Webhooks |
GraphQL subscriptions over /graphql | ARC → authenticated client | User JWT in graphql-ws connection params | Real-time application UI events; not a durable sync queue. |
GET /api/events/stream | ARC → authenticated user | User JWT | In-memory SSE notifications for quote email delivery/open/click/bounce/reply events owned by that user. |
/webhooks/payments/* | Payment provider → ARC | Provider-specific signature/config | Inbound gateway callbacks; not a customer outbound webhook subscription. |
/webhooks/postmark/* and document-delivery callbacks | Mail provider → ARC | Provider callback contract | Inbound email/delivery processing. |
/api/service/* | Your system → ARC | Tenant API key | Deterministic server-to-server reads and commands, not event delivery; pair it with webhooks for notification, and use its updatedAfter lists to catch up. |
Quote-email SSE
An authenticated user can open:
GET https://<arc-host>/api/events/stream
Authorization: Bearer <arc-access-token>
Accept: text/event-stream
The stream may carry events shaped like:
{
"type": "quote.email.delivery",
"quoteId": "<quote-id>",
"quoteNumber": "<quote-number>",
"data": { "activityId": "<activity-id>" },
"timestamp": "2026-09-18T12:00:00.000Z"
}
Current event types include delivery, open, click, bounce, and reply. Delivery is filtered to the quote owner and organization of the JWT. The stream is process-local and does not provide a durable replay cursor; reconnect and reconcile from GraphQL if your application cannot afford to miss an event.
Provider callbacks are inbound, not your feed
Payment, email, billing and other callback routes are called by providers or by ARC's own infrastructure. Do not post arbitrary data to them and do not build a customer integration against a route unless Growmax gives you the provider-specific contract and signature configuration.
Combine webhooks with reconciliation
Webhooks are not a complete change feed. A notification can be missed if your endpoint is disabled or down for longer than the retry window. Run a reconciliation job alongside your webhook receiver:
- store the last successful sync checkpoint per tenant and resource;
- page through the relevant GraphQL/service API list;
- upsert by ARC opaque id;
- compare
updatedAt, status, totals, and document numbers; - retry transient failures with backoff and keep an operator-visible dead-letter state.
For the webhook side, see Webhooks → Build a reliable receiver. For paging and retry rules, see Errors, pagination and idempotency.