Developers/Webhooks

Event-driven integration

React to durable operations

Receive signed lifecycle events when documents, batches, videos, workflows, reviews, and packets reach meaningful states.

Available event typesSubscribe to meaningful state changes6 event groups
Document lifecycle

document.uploaded, document.chunked, document.embedded, and document.failed.

Batch processing

batch.completed notifies applications after a governed multi-document operation reaches completion.

Video intelligence

video.processing.completed signals that timeline, transcript, frames, chunks, and final processing state are available.

Vertical workflows

workflow.completed marks a completed healthcare, finance, talent, lease, or other governed workflow run.

Human review

review.approved communicates that a reviewer accepted the governed output.

Packets

packet.generated signals that a downloadable or ingestible packet is ready.

Webhook quick startConfigure an endpoint and receive an event3 steps

A webhook needs an application with events:read and events:write, an application-granted workspace, and a publicly resolvable HTTPS receiver. DocIntel rejects localhost, private-address, metadata, and plain HTTP targets.

1. Shared configuration
export API="https://docintel.adar.agomoniai.com/api/v1"
export DOCINTEL_ACCESS_TOKEN="YOUR_REST_AUDIENCE_ACCESS_TOKEN"
export WORKSPACE_ID="YOUR_GRANTED_WORKSPACE_UUID"
export WEBHOOK_URL="https://hooks.example.com/docintel/events"

export AUTH="Authorization: Bearer $DOCINTEL_ACCESS_TOKEN"
export WS="X-DocIntel-Workspace-ID: $WORKSPACE_ID"
2. Register the subscription
curl -sS -X POST "$API/event-subscriptions" \
  -H "$AUTH" \
  -H "$WS" \
  -H "Content-Type: application/json" \
  --data "$(jq -cn \
    --arg workspace_id "$WORKSPACE_ID" \
    --arg webhook_url "$WEBHOOK_URL" \
    '{
      event_types:[
        "document.embedded",
        "video.processing.completed",
        "workflow.completed",
        "packet.generated"
      ],
      workspace_id:$workspace_id,
      webhook_url:$webhook_url
    }')" \
  | tee /tmp/docintel-webhook-subscription.json \
  | jq
3. Store the one-time secret
export SUBSCRIPTION_ID="$(jq -r '.id' /tmp/docintel-webhook-subscription.json)"
export DOCINTEL_WEBHOOK_SECRET="$(jq -r '.webhook_secret' /tmp/docintel-webhook-subscription.json)"

test -n "$DOCINTEL_WEBHOOK_SECRET" && \
  test "$DOCINTEL_WEBHOOK_SECRET" != "null" && \
  echo "Signing secret stored for this shell session."
The secret is shown once

Move DOCINTEL_WEBHOOK_SECRET into your secret manager immediately. Subscription list responses intentionally omit it.

Receiver exampleVerify the signature over the raw bodyFastAPI

DocIntel signs {timestamp}.{raw_request_body} with HMAC-SHA256. Verify the raw bytes before JSON parsing, allow either v1 signature during secret rotation, reject stale timestamps, and persist the event ID as a unique idempotency key.

FastAPI receiver
import hashlib
import hmac
import json
import os
import time

from fastapi import FastAPI, Header, HTTPException, Request

app = FastAPI()
secret = os.environ["DOCINTEL_WEBHOOK_SECRET"].encode()

@app.post("/docintel/events", status_code=202)
async def receive_docintel_event(
    request: Request,
    x_docintel_timestamp: str = Header(),
    x_docintel_signature: str = Header(),
    x_docintel_event_id: str = Header(),
):
    raw_body = await request.body()
    try:
        timestamp = int(x_docintel_timestamp)
    except ValueError as exc:
        raise HTTPException(401, "Invalid timestamp") from exc

    if abs(int(time.time()) - timestamp) > 300:
        raise HTTPException(401, "Stale webhook")

    signed_payload = x_docintel_timestamp.encode() + b"." + raw_body
    expected = hmac.new(secret, signed_payload, hashlib.sha256).hexdigest()
    received = [
        item.split("=", 1)[1]
        for item in x_docintel_signature.split(",")
        if item.startswith("v1=")
    ]
    if not any(hmac.compare_digest(expected, value) for value in received):
        raise HTTPException(401, "Invalid signature")

    event = json.loads(raw_body)
    # Persist x_docintel_event_id with a UNIQUE constraint before enqueueing work.
    # Return 2xx only after durable acceptance.
    return {"accepted": True, "event_id": x_docintel_event_id,
            "event_type": event["event_type"]}
Send and testChoose the right event pathTest, trigger, replay
Synthetic endpoint test

From DocIntel, open Applications and Credentials, select the application and its Webhooks tab, then choose Send test event. DocIntel creates and signs a real webhook.test delivery.

Real lifecycle event

Run the subscribed operation, such as embedding a document, completing video processing, finishing a workflow, approving a review, or generating a packet. The backend emits the event; clients do not inject lifecycle events directly.

Replay an event

Use the public API to send an existing event again after repairing the receiver. Replay remains signed and creates delivery records for matching active subscriptions.

Send a synthetic test through the management API
export DOCINTEL_SESSION_TOKEN="YOUR_DOCINTEL_SIGN_IN_TOKEN"
export CLIENT_ID="YOUR_APPLICATION_CLIENT_ID"
export DEVELOPER_SUBSCRIPTION_ID="YOUR_APPLICATION_WEBHOOK_UUID"

curl -sS -X POST \
  "https://docintel.adar.agomoniai.com/api/v1/developer/apps/$CLIENT_ID/webhooks/$DEVELOPER_SUBSCRIPTION_ID/test" \
  -H "Authorization: Bearer $DOCINTEL_SESSION_TOKEN" \
  | jq

The management test endpoint uses the signed-in DocIntel session token because it manages your application. Runtime REST endpoints use the OAuth access token whose resource is https://docintel.adar.agomoniai.com/api/v1.

Trigger a real document.embedded event
export DOCUMENT_ID="YOUR_CHUNKED_DOCUMENT_UUID"

curl -sS -X POST "$API/documents/$DOCUMENT_ID/embedding" \
  -H "$AUTH" \
  -H "$WS" \
  | jq
Find and replay an existing event
curl -sS "$API/events?resource_type=document&limit=25" \
  -H "$AUTH" \
  -H "$WS" \
  | tee /tmp/docintel-events.json \
  | jq

export EVENT_ID="$(jq -r \
  '.events[] | select(.event_type == "document.embedded") | .id' \
  /tmp/docintel-events.json | head -1)"

curl -sS -X POST "$API/events/$EVENT_ID/replay" \
  -H "$AUTH" \
  -H "$WS" \
  | jq
Inspect delivery status
curl -sS \
  "$API/webhook-deliveries?subscription_id=$SUBSCRIPTION_ID&limit=25" \
  -H "$AUTH" \
  -H "$WS" \
  | jq '.deliveries[] | {
      id,
      event_type,
      status,
      attempt_count,
      last_http_status,
      last_error
    }'
Delivery contractVerify before processingPayload and headers
Actual event envelope
{
  "id": "event_uuid",
  "api_version": "2026-08-31",
  "type": "document.embedded",
  "sequence_number": 42,
  "event_type": "document.embedded",
  "resource_type": "document",
  "resource_id": "document_uuid",
  "payload": {"status": "embedded", "chunk_count": 32},
  "workspace_id": "workspace_uuid",
  "created_at": "2026-08-31T20:00:00+00:00"
}
Delivery headers
X-DocIntel-Event: document.embedded
X-DocIntel-Event-ID: event_uuid
X-DocIntel-Timestamp: 1788225600
X-DocIntel-Signature: v1=HMAC_SHA256_HEX
X-DocIntel-Signature-SHA256: HMAC_SHA256_HEX
Idempotency-Key: event_uuid
Content-Type: application/json

The X-DocIntel-Signature header can contain two comma-separated v1 signatures during the 24-hour secret-rotation overlap. Accept a request when either value verifies with the corresponding active secret.

ReliabilityAssume at-least-once delivery6 safeguards
Return 2xx only after durable acceptanceDeduplicate by event IDProcess asynchronouslyRetry transient failures with jitterQuarantine persistent failuresReconcile with the status API
Ordering

Events may arrive late or out of order. Compare resource version and event time, then read the current resource state before applying irreversible actions.

Delivery operationsManage the complete endpoint lifecycle8 operations
Register only public HTTPS endpointsChoose explicit events and an application-granted workspaceStore the signing secret shown onceSend a synthetic test eventInspect response codes and delivery attemptsReplay failed deliveriesRotate signing secrets with overlapDisable or delete unused endpoints
Workspace matching matters

An event is delivered only when the subscription is active, includes the event type, and its workspace is granted to the application.

SecurityProduction endpoint requirementsVerification and isolation

Use HTTPS, verify HMAC over the timestamp and raw body before parsing JSON, reject stale timestamps, deduplicate by event ID, rotate signing secrets, redact payloads in logs, enforce body-size limits, and isolate webhook processing from interactive API traffic.