Webhooks
RCM is mostly an asynchronous API. Uploads, validation, invoice assignment — they all return 202 Accepted immediately and deliver the outcome later. The delivery channel is webhooks: HTTPS POSTs to an endpoint you control, authenticated with either an HMAC-SHA256 signature (default) or HTTP Basic credentials so you can verify they actually came from OSIGU.
This page is the conceptual overview. The full payload contracts live in Webhook events.
When does RCM call you
| Trigger | Event types |
|---|---|
You uploaded a support file via v2 with support_file_code omitted | DOCUMENT_CLASSIFICATION_COMPLETED, DOCUMENT_CLASSIFICATION_FAILED |
You uploaded a support file via v1 (or via v2 with support_file_code set) | DOCUMENT_VALIDATION_COMPLETED, DOCUMENT_VALIDATION_REJECTED |
| DVS finished validating a support file uploaded via the v2 auto-classify flow | DOCUMENT_VALIDATION_COMPLETED, DOCUMENT_VALIDATION_REJECTED |
RCM also emits account, charge, invoice and settlement-batch events (ACCOUNT_*, CHARGE_*, INVOICE_*, SETTLEMENT_GROUP_*). Their payloads are in preview and each family is enabled per provider by OSIGU. The full list is in the Event catalog.
Why webhooks instead of polling
The DVS classification + validation pipeline takes anywhere from 5 to 60 seconds per document, depending on file size, content complexity, and the rules that apply. Polling that latency for every upload would burn through rate limits and add 10–30 seconds of artificial latency to your UX. With webhooks:
- RCM pushes the result the moment it's ready.
- You don't have to keep state in your client about pending support files.
- The same mechanism delivers retries, late-arriving outcomes, and dead-letter notifications.
The trade-off is that you have to expose an HTTPS endpoint and verify authentication correctly.
Receiver responsibilities
A correct webhook receiver does three things:
- 1Verify authentication before parsing
For HMAC subscriptions, reject anything where
X-RCM-Signaturedoesn't match what you compute fromX-RCM-Timestamp + raw_body(no separator) using your shared secret, Base64-encoded. For Basic subscriptions, validate theAuthorization: Basicheader. Use a constant-time comparison. See Authentication and Signature verification. - 2Be idempotent on `event_id`
The same
event_idmay be delivered more than once if your ACK is lost or if you 5xx-ed a previous attempt. Useevent_id(also in theX-RCM-Event-IDheader) as your dedupe key. - 3Return 2xx quickly
Anything else (non-2xx or a timeout) triggers a retry. Persist the event to your queue first, ack to RCM, then process. Don't do the heavy work synchronously in the request handler.
Retry policy
RCM treats any non-2xx response or a connection/read timeout as a failure. Failed events are re-attempted by the dispatcher on its next scheduling cycle (roughly once per minute) while the event is still pending — delivery is at-least-once, so your receiver must be idempotent.
After several consecutive failures against the same destination, the subscription's circuit breaker opens and delivery is suspended to protect a struggling receiver. It resets automatically after a timeout, or you can reset it manually once the receiver is healthy again (see below).
Subscription model
You configure where RCM should POST events via the webhook-subscriptions API:
# Create a subscription (HMAC — the default)
curl -X POST https://sandbox.osigu.com/rcm/v1/integration/webhooks \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"webhook_url": "https://your-system.example.com/webhooks/osigu-rcm",
"subscribed_event_types": [
"DOCUMENT_VALIDATION_COMPLETED",
"DOCUMENT_VALIDATION_REJECTED"
],
"description": "Production receiver"
}'
The base path is /rcm/v1/integration/webhooks; sandbox is https://sandbox.osigu.com and production is https://api.osigu.com. Choose the authentication mechanism with auth_type — see Authentication. See the full API under Webhook Subscriptions in the reference.
Subscriptions support:
- Selective event subscription (
subscribed_event_types) — subscribe only to validation events if you don't care about classification. - Custom headers forwarded on every delivery.
- Pause / resume — toggle delivery without losing the subscription configuration.
- Manual circuit-breaker reset — if a destination has been failing for so long that RCM tripped its circuit-breaker, you can reset it after fixing the receiver.
For HMAC subscriptions, the signing secret is generated by RCM and shared with you securely out of band — it is not returned by the API. For Basic subscriptions, the basic_auth_client_secret you provide is stored encrypted and never returned either. See Authentication.
Local testing
To exercise the webhook flow without a real public endpoint:
- ngrok —
ngrok http 3000gives you ahttps://....ngrok.ioURL routed to localhost. - Cloudflare Tunnel — same idea, no rate limits, requires a Cloudflare account.
Register the tunnel URL as a sandbox subscription, upload a test support file via /v1/support-files/upload, and observe the event landing locally. Detailed walk-through in the implement-a-webhook-receiver guide.