Skip to main content

5. Webhooks

Overview

When an event occurs (document processed, integration revoked), OneConnect by Shine sends an HTTP POST to the webhook URL you will provide to us:

POST https://your-product-url.com/webhooks/one-connect
Content-Type: application/cloudevents+json

Use a single HTTPS endpoint. The event kind is carried only in the JSON body: the CloudEvents type field. Two values exist today:

type (in JSON body)Trigger
DocumentStatusAn imported invoice has been accepted or refused by the Cegid accounting tool.
RevocationAn integration (Id/Secret) has been revoked (by the client, the accounting firm, or a business event).

Format: CloudEvents v1.0

All payloads follow the CloudEvents v1.0 — JSON format specification.

Common envelope:

FieldTypeDescription
specversion"1.0"CloudEvents version
idUUIDUnique event identifier
sourcestringOneConnect by Shine public URL (e.g. https://api.oneconnect.shine.co)
typestring"DocumentStatus" or "Revocation"
datacontenttype"application/json"Always JSON
timeISO 8601Event timestamp
dataobjectBusiness content (see below)

DocumentStatus event — Invoice accepted

{
"specversion": "1.0",
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"source": "https://api.oneconnect.shine.co",
"type": "DocumentStatus",
"datacontenttype": "application/json",
"time": "2026-04-03T14:30:00.000Z",
"data": {
"integrationId": "550e8400-e29b-41d4-a716-446655440000",
"documentId": "660f9500-f30c-52e5-b827-ff2345678901",
"externalReference": "INV-2026-042",
"documentState": "Accepted"
}
}

DocumentStatus event — Invoice refused

{
"specversion": "1.0",
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"source": "https://api.oneconnect.shine.co",
"type": "DocumentStatus",
"datacontenttype": "application/json",
"time": "2026-04-03T15:00:00.000Z",
"data": {
"integrationId": "550e8400-e29b-41d4-a716-446655440000",
"documentId": "660f9500-f30c-52e5-b827-ff2345678901",
"externalReference": "INV-2026-042",
"documentState": "Refused",
"rejectedDatetime": "2026-04-03T14:58:00.000Z",
"rejectionReason": "Document illisible ou incomplet"
}
}

data fields for DocumentStatus

FieldTypeDescription
integrationIdstring | nullThe integration identifier (UUID), the same value used in the integrationId path parameter of the import API. null if not resolved (should not occur in normal operation).
documentIdstringDocument identifier (the one returned at import time).
externalReferencestring | nullYour external reference, if provided at import.
documentState"Accepted" or "Refused"Final document status.
rejectedDatetimestring | null(Refused only) Rejection timestamp (ISO 8601).
rejectionReasonstring | null(Refused only) Rejection reason.

Revocation event — Integration revoked

{
"specversion": "1.0",
"id": "c3d4e5f6-a7b8-9012-cdef-123456789012",
"source": "https://api.oneconnect.shine.co",
"type": "Revocation",
"datacontenttype": "application/json",
"time": "2026-04-03T16:00:00.000Z",
"data": {
"integrationId": "550e8400-e29b-41d4-a716-446655440000"
}
}

data fields for Revocation

FieldTypeDescription
integrationIdstringThe identifier (UUID) of the revoked integration.

note: both DocumentStatus and Revocation use the same field name integrationId in data (camelCase).


Signature verification (X-OneConnect-Webhook-Signature)

Webhook signing is always enabled in production on the OneConnect by Shine side. Every webhook POST includes a header:

X-OneConnect-Webhook-Signature: eyJhbGciOiJSUzUxMiIs...

This is a compact RS512 JWT whose claims let you verify the authenticity and integrity of the body:

ClaimDescription
issOneConnect by Shine public URL (issuer)
jtiUnique JWT identifier
body_sha256Hex SHA-256 hash of the raw POST body
ce_typeCloudEvents type (DocumentStatus or Revocation)
iat / expIssuance and expiration timestamps

You must implement signature verification before accepting events in production.

To verify:

  1. Fetch the public keys: GET https://api.oneconnect.shine.co/.well-known/jwks.json
  2. Identify the key by the kid in the JWT header.
  3. Verify the RS512 signature.
  4. Compute the hex SHA-256 of the received body and compare it to the body_sha256 claim.

Important: compute the SHA-256 over the raw request body bytes exactly as received, before any JSON parsing or re-serialization.


Delivery guarantees and idempotency

Webhooks are delivered at-least-once. In edge cases (e.g. your server processes the request but the response times out before reaching OneConnect by Shine), the same event may be delivered more than once with the same CloudEvents id.

Your implementation must deduplicate incoming events:

  • Store the id field of every processed event.
  • On each incoming webhook, check whether you have already seen that id. If so, ignore the duplicate.
  • The id is a UUID generated once per event and does not change across retries.

Retry policy

Respond with any HTTP 2xx to acknowledge receipt. Anything else (including timeouts) is treated as a failure and retried automatically.

Requests time out after 10 seconds.

Retry schedule:

  1. Immediate burst — up to 3 retries at 5 s, 10 s, then 30 s after the initial failure.
  2. Scheduled retries — if the burst also fails, OneConnect by Shine keeps retrying automatically, approximately every 5 minutes, for up to 48 hours from the first delivery attempt. After 48 hours, retries stop.

If you expect a long outage and need help with pending deliveries, contact the OneConnect support team via the support channel provided during onboarding.