Extraction webhooks
Configure a webhook URL to receive a POST notification whenever an extraction job reaches completed state, instead of polling the API.
Configuring the webhook
Endpoint: PUT /v2/extract-settings
Two settings control how webhooks are sent:
| Field | Type | Default | Description |
|---|---|---|---|
webhookUrl |
string | null |
null |
URL that receives POST notifications. Set to null to disable. |
webhookFormat |
"json" | "markdown" |
"json" |
Format of the request body — JSON object or Markdown document. |
import { Exabase } from "@exabase/sdk";
const api = new Exabase({
apiKey: process.env.EXABASE_API_KEY,
});
await api.extractSettings.updateSettings({
webhookUrl: "https://your-server.example.com/webhooks/exabase",
webhookFormat: "json",
});
await api.extractSettings.updateSettings({
webhookUrl: "https://your-server.example.com/webhooks/exabase",
webhookFormat: "markdown",
});
curl https://api.exabase.io/v2/extract-settings \
-X PUT \
-H 'X-Api-Key: <EXABASE_API_KEY>' \
-H 'Content-Type: application/json' \
-d '{
"webhookUrl": "https://your-server.example.com/webhooks/exabase",
"webhookFormat": "json"
}'
curl https://api.exabase.io/v2/extract-settings \
-X PUT \
-H 'X-Api-Key: <EXABASE_API_KEY>' \
-H 'Content-Type: application/json' \
-d '{
"webhookUrl": "https://your-server.example.com/webhooks/exabase",
"webhookFormat": "markdown"
}'
To disable webhooks set webhookUrl to null.
Checking current settings
Endpoint: GET /v2/extract-settings
const settings = await api.extractSettings.get();
console.log(settings.webhookUrl);
curl https://api.exabase.io/v2/extract-settings \
-H 'X-Api-Key: <EXABASE_API_KEY>'
Webhook payload
Exabase sends a POST request to your URL with an X-Trace-Id header for correlation. The body format depends on webhookFormat:
json(default) —Content-Type: application/json. The body is the fullExtractJobobject, identical to what you'd get fromGET /v2/extract/{jobId}.markdown—Content-Type: text/markdown. The body is a human-readable Markdown document built from the extraction data (see Output formats).
Example JSON payload:
{
"id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"workspaceId": "...",
"state": "completed",
"kind": "document",
"name": "Invoice #1042",
"extraction": {
"common": { "mimeType": "application/pdf", "size": 204800 },
"document": {
"pages": 2,
"documentType": "invoice",
"structured": { "vendor": "Acme Corp", "total": 100.00 }
}
}
}
Return any 2xx status code to acknowledge delivery. Non-2xx responses or
network timeouts are retried with exponential backoff.
Manual trigger
You can dispatch a webhook for any existing job without reprocessing it. Useful for testing your endpoint or replaying a missed delivery.
Endpoint: POST /v2/extract/{jobId}/webhook/trigger
const { traceId } = await api.extract.triggerWebhook({ jobId: "job-id" });
console.log("dispatched with trace id:", traceId);
curl https://api.exabase.io/v2/extract/<jobId>/webhook/trigger \
-X POST \
-H 'X-Api-Key: <EXABASE_API_KEY>'
Webhook logs
Each dispatch attempt is logged. Use the logs to inspect delivery status, response codes, and response bodies.
Endpoints:
GET /v2/extract/{jobId}/webhook-logs— list all attempts for a jobGET /v2/extract/{jobId}/webhook-logs/{logId}— full detail including request payload and response body
const logs = await api.extract.listWebhookLogs({ jobId: "job-id" });
for (const log of logs.items) {
console.log(log.attemptNumber, log.status, log.statusCode);
}
curl https://api.exabase.io/v2/extract/<jobId>/webhook-logs \
-H 'X-Api-Key: <EXABASE_API_KEY>'