heyvisa

Webhooks

Webhooks deliver asynchronous events to your HTTPS endpoint the moment something interesting happens. They are the recommended way to know when a report has finished — no polling required.

Event types

EventWhen it fires
report.completedA queued report has finished analysis successfully.
report.failedA report could not be completed (e.g., unreadable documents).
document.processedA document upload finished OCR + validation.
document.rejectedA document failed safety / format checks and was discarded.

report.completed payload

http
POST /your-endpoint HTTP/1.1
Content-Type: application/json
HeyVisa-Event: report.completed
HeyVisa-Signature: t=1718099274,v1=4f3a1c...

{
  "id": "evt_01HXYZ...",
  "type": "report.completed",
  "created_at": "2026-06-11T09:21:47Z",
  "data": {
    "id": "rep_01HXYZ...",
    "risk_score": 72,
    "risk_band": "medium",
    "completed_at": "2026-06-11T09:21:47Z"
  }
}

report.failed payload

json
{
  "id": "evt_01HXYZ...",
  "type": "report.failed",
  "data": {
    "id": "rep_01HXYZ...",
    "error": {
      "code": "document_unreadable",
      "message": "Passport image is too blurry to process."
    }
  }
}

document.processed payload

json
{
  "id": "evt_01HXYZ...",
  "type": "document.processed",
  "data": {
    "id": "doc_01HXYZpassport",
    "type": "passport",
    "status": "analysed",
    "red_flags": []
  }
}

Delivery and retries

We attempt delivery from a fixed pool of egress IPs and expect a 2xx response within 10 seconds. Any non-2xx, timeout, or connection error is retried with exponential backoff over 24 hours.

AttemptDelay from previousCumulative
10s
230 s30 s
32 min2.5 min
410 min12.5 min
51 hour~1h
66 hours~7h
712 hours~19h

After the final failed attempt the event is marked dead-letter and appears in the dashboard under Settings → Webhooks where you can replay it manually.

Verify the signature
Every webhook includes a HeyVisa-Signature header. See Webhook Verification for HMAC SHA-256 verification samples in Node.js and Python.

Idempotency

Each event has a unique id (evt_…). Store recently processed IDs and drop duplicates — retries may deliver the same event more than once.