Skip to main content
POST
/
_reference
/
outbound-webhooks
/
result_ready
result.ready (outbound to your registered HTTPS URL)
curl --request POST \
  --url https://api-test.idunox.com/_reference/outbound-webhooks/result_ready \
  --header 'Content-Type: application/json' \
  --header 'X-IduScore-Delivery-Id: <x-iduscore-delivery-id>' \
  --header 'X-IduScore-Event: <x-iduscore-event>' \
  --header 'X-IduScore-Signature: <x-iduscore-signature>' \
  --header 'X-IduScore-Timestamp: <x-iduscore-timestamp>' \
  --data '
{
  "completedAt": "2026-04-24T00:49:32.389Z",
  "eventType": "result.ready",
  "partnerSubmissionId": "SYN-SUB-20260331-000001",
  "reportId": "8b37c3c5-a223-456b-9c96-ad2d0e2e2ce6",
  "resultId": "db2550ba-4c7f-4e7f-95d8-0a064f368f14",
  "status": "completed",
  "statusLabel": "Completed",
  "submissionId": "8d70fed5-8f01-410d-87bd-8755725d7c6f"
}
'
This is not a route on the Idunox API. It documents the POST request the platform sends to your registered webhook URL when a result becomes ready.

Registering a webhook URL

Contact partner@idunox.com to register:
  • Your HTTPS callback URL
  • The webhook API key your endpoint expects (sent as X-Api-Key by default)
  • Your webhook signing secret for HMAC verification

Webhook headers

The platform sends the following headers on every delivery:
HeaderDescription
X-IduScore-EventAlways result.ready for this event
X-IduScore-Delivery-IdUUID for this delivery attempt (use for idempotency on your side)
X-IduScore-TimestampUnix time in seconds (integer as decimal string)
X-IduScore-SignatureHMAC-SHA256 signature formatted as v1=<hex>
X-Api-KeyOptional. When registered with Idunox, the API key you provide for authenticating inbound webhook POSTs on your server (not your POST /v1/submissions API key)
Inbound submission calls (POST /v1/submissions) use your partner API key. Outbound webhooks use a separate webhook API key plus HMAC signature — configure both with Idunox during integration.

Verifying the signature

Verify every delivery before processing:
  1. Concatenate: X-IduScore-Timestamp + "." + raw_request_body
  2. Compute HMAC-SHA256 over that string using your webhook signing secret.
  3. Compare to the hex digest in X-IduScore-Signature (after the v1= prefix).
  4. Reject deliveries where the timestamp is more than 5 minutes old.
import hmac, hashlib, time

def verify(secret: str, timestamp: str, body: bytes, signature: str) -> bool:
    if abs(time.time() - int(timestamp)) > 300:
        return False
  signed_payload = timestamp.encode() + b"." + body
  mac = hmac.new(secret.encode(), signed_payload, hashlib.sha256)
    expected = "v1=" + mac.hexdigest()
    return hmac.compare_digest(expected, signature)

Responding to the webhook

Return any 2xx status to acknowledge the delivery. Non-2xx responses and transport failures may be retried by the platform.

Webhook body

The body identifies the completed result so you can retrieve it:
{
  "eventType": "result.ready",
  "resultId": "db2550ba-4c7f-4e7f-95d8-0a064f368f14",
  "submissionId": "8d70fed5-8f01-410d-87bd-8755725d7c6f",
  "partnerSubmissionId": "your-ref-001",
  "reportId": "8b37c3c5-a223-456b-9c96-ad2d0e2e2ce6",
  "status": "completed",
  "statusLabel": "Completed",
  "completedAt": "2026-04-27T00:49:32.389Z"
}
Use the resultId to call GET /v1/results/{resultId} and retrieve the full result.

Headers

X-IduScore-Event
enum<string>
required

Always result.ready for this flow (duplicates eventType in the body for routing layers).

Available options:
result.ready
X-IduScore-Delivery-Id
string<uuid>
required

Idempotency / support id for this delivery attempt.

X-IduScore-Timestamp
string
required

Unix time in seconds (integer as decimal string) used in the HMAC input.

Pattern: ^[0-9]+$
X-IduScore-Signature
string
required

HMAC-SHA256 signature, formatted as v1=<hex>.

Pattern: ^v1=[0-9a-f]+$
X-Api-Key
string

Present when your webhook endpoint is configured with an outbound API key (Health Yourself and other partners). Header name may be customized (e.g. Authorization: Bearer …) during registration.

Body

application/json

Outbound result.ready webhook JSON body (HTTPS POST). Minimal partner notification: correlate by ids and load full detail via GET result APIs. Does not include internal tenant UUIDs, job ids, model output, or correlation metadata (those remain in delivery records server-side). Breaking change from the prior envelope that included inference, tenantId, and processingJobId. Not an HTTP path on this API; documented here as the partner contract for callbacks.

eventType
enum<string>
required
Available options:
result.ready
resultId
string<uuid>
required
submissionId
string<uuid>
required
partnerSubmissionId
string | null
required
status
enum<string>
required

Stable public slug for submission pipeline state (partner JSON).

Available options:
received,
validating,
validated,
processing,
completed,
failed,
rejected
statusLabel
string
required
Minimum string length: 1
completedAt
string<date-time>
required
reportId
string<uuid>

Present when a report bundle artifact id is available on the result (prefers PDF, then JSON, then HTML).

Response

Webhook received (any 2xx is treated as success)