Graphon API

Webhook events

Every webhook event type and its data fields, the signature headers, and the retry schedule.

View as Markdown

Graphon sends each event as a JSON POST to the webhook URL. To create a webhook and verify its events, read Receive events with webhooks.

Event body

Every event has the same top-level fields.

FieldTypeDescription
idstringThe event ID, which starts with evt. It equals the webhook-id header.
typestringThe event type.
timestampstringWhen the change happened, in UTC (ISO 8601). Not when Graphon sent the POST.
workspaceIdstringThe workspace ID.
dataobjectThe fields of the event type.
  • An event holds IDs, a status, and error codes. It never holds object content or metadata values. Read the object with the Storage API when you need it.
  • Graphon can add event types and fields. Ignore a type or a field that you do not know, and answer 2xx. A webhook with eventTypes: null also gets types that Graphon adds later.

Event types

TypeWhen Graphon sends it
object.indexedAn object version became searchable. Its indexing status moved to ready.
object.indexing_failedAn object version could not be indexed. Its indexing status moved to failed or unsupported.
webhook.testYou called Test a webhook. Only that call sends it. A webhook cannot filter for it, and the delivery log does not keep it.

object.indexed

An object version became searchable. Its indexing status moved to ready.

FieldTypeDescription
data.object.bucketIdstringThe bucket ID.
data.object.keystringThe object key.
data.object.versionIdstringThe object version. A newer version of the same key has its own events.
data.object.statusstringready

Example

{
  "id": "evtW2nC6vJ0hS",
  "type": "object.indexed",
  "timestamp": "2026-10-14T09:05:12.481Z",
  "workspaceId": "wspq7ws2np5l8z4",
  "data": {
    "object": {
      "bucketId": "bktA1b2C3d4E5",
      "key": "incidents/timeout.json",
      "versionId": "ver_3f9c2a7d1e4b4c8a9f0d6b2e5a1c7d3f",
      "status": "ready"
    }
  }
}

object.indexing_failed

An object version could not be indexed. Its indexing status moved to failed or unsupported.

FieldTypeDescription
data.object.bucketIdstringThe bucket ID.
data.object.keystringThe object key.
data.object.versionIdstringThe object version. A newer version of the same key has its own events.
data.object.statusstringfailed: indexing stopped with an error. unsupported: Graphon refused the object, for example for its size or its metadata.
data.object.error.codestringFor failed, the error code from the index, such as ingest_failed or index_timeout. For unsupported, the refusal code, such as invalid_metadata.
data.object.error.messagestringText for a person to read. Do not parse it.

Example

{
  "id": "evtK5mP9qL3dF",
  "type": "object.indexing_failed",
  "timestamp": "2026-10-14T09:07:40.019Z",
  "workspaceId": "wspq7ws2np5l8z4",
  "data": {
    "object": {
      "bucketId": "bktA1b2C3d4E5",
      "key": "incidents/scan.pdf",
      "versionId": "ver_8b1e4d2a9c7f4e3b8a6d5c1f0e9b2a74",
      "status": "failed",
      "error": {
        "code": "ingest_failed",
        "message": "The file is not a readable PDF."
      }
    }
  }
}

webhook.test

You called Test a webhook. Only that call sends it. A webhook cannot filter for it, and the delivery log does not keep it.

FieldTypeDescription
data.webhook.idstringThe webhook ID.

Example

{
  "id": "evtH7jN2cR6tY",
  "type": "webhook.test",
  "timestamp": "2026-10-14T09:01:00.112Z",
  "workspaceId": "wspq7ws2np5l8z4",
  "data": {
    "webhook": {
      "id": "whkN4vB7qX2mZ"
    }
  }
}

Headers

HeaderValue
webhook-idThe event ID. Every retry and replay of the event sends the same value.
webhook-timestampWhen Graphon sent this POST, in Unix seconds. Each attempt has a new value.
webhook-signaturev1, and the base64 HMAC-SHA256 of {webhook-id}.{webhook-timestamp}.{body}. The key is the base64-decoded part of the secret after whsec_. During a secret rotation, the header holds two signatures, separated by a space, the new one first.
content-typeapplication/json
user-agentGraphon-Webhooks/1

This is the Standard Webhooks scheme. Check each POST with the standardwebhooks library for Node.js or Python. Refuse a POST whose timestamp is more than 5 minutes away from your clock.

Retries

Graphon delivers each event at least once, in any order. It makes up to 10 attempts over about 75 hours.

AttemptWait after the previous attemptAbout this long after the first
1Sent at once0
25 seconds5 seconds
35 minutes5 minutes
430 minutes35 minutes
52 hours2 hours 35 minutes
65 hours7 hours 35 minutes
710 hours17 hours 35 minutes
814 hours31 hours 35 minutes
920 hours51 hours 35 minutes
1024 hours75 hours 35 minutes
  • Each wait varies by up to 10% either way.
  • A Retry-After header on a 429 or 5xx answer replaces a shorter wait, up to 24 hours.
  • A replay starts a new round of up to 10 attempts.
AnswerResult
2xxSucceeded.
429, 5xx, no answer in 15 seconds, a network error, or a TLS errorRetried. After the last attempt, failed.
3xxFailed. Graphon does not follow redirects.
410Failed, and Graphon turns the webhook off.
Any other 4xxFailed.

Graphon also turns a webhook off when a delivery fails, the webhook is older than 72 hours, and it got no 2xx answer in the last 72 hours. A webhook that Graphon turned off shows disabledReason failing. The delivery log keeps each event for 30 days.

Was this page helpful?