Skip to main content

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

TriggerEvent types
You uploaded a support file via v2 with support_file_code omittedDOCUMENT_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 flowDOCUMENT_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:

  1. 1Verify authentication before parsing

    For HMAC subscriptions, reject anything where X-RCM-Signature doesn't match what you compute from X-RCM-Timestamp + raw_body (no separator) using your shared secret, Base64-encoded. For Basic subscriptions, validate the Authorization: Basic header. Use a constant-time comparison. See Authentication and Signature verification.

  2. 2Be idempotent on `event_id`

    The same event_id may be delivered more than once if your ACK is lost or if you 5xx-ed a previous attempt. Use event_id (also in the X-RCM-Event-ID header) as your dedupe key.

  3. 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.
Secrets are never returned

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:

  • ngrokngrok http 3000 gives you a https://....ngrok.io URL 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.