For AI agents: a documentation index is available at the root level at /llms.txt and /llms-full.txt. Append /llms.txt to any URL for a page-level index, or .md for the markdown version of any page.
GuidesAPI ReferenceChangelog
GuidesAPI ReferenceChangelog
  • Introduction
    • Overview
    • Quickstart
    • Authentication
  • Core Guides
    • Document Extraction
    • Workflow Runs
    • Event Subscriptions
On this page
  • When to use events
  • Available events
  • Setup
  • Event payload model
  • Delivery headers
  • Verifying signatures
  • Retry and idempotency
  • Related reference
Core Guides

Event Subscriptions

Was this page helpful?
Previous
Built with

Event subscriptions let Plextera push product events to your webhook endpoint. Use them when your integration should react to completed, failed, or rejected processing without polling.

When to use events

PatternRecommended for
Polling onlySimple backend integrations, local testing, or flows where delayed processing is acceptable.
Events onlyProduction integrations that need push notifications and lower API traffic.
Events plus pollingRobust production integrations. Use events for the normal path and polling as a fallback status check.

A common production pattern is: subscribe to terminal events, process webhook deliveries immediately, and periodically poll resources that have not completed after an expected time window.

Available events

EventDelivered whenPayload
document-insights.extraction.completedA document extraction reaches COMPLETED.Full extraction with output.
document-insights.extraction.failedA document extraction reaches FAILED.Extraction state with error.
document-insights.extraction.rejectedA document extraction reaches REJECTED.Extraction state with error.
workflow.run.completedA workflow run reaches COMPLETED.Full workflow run with step outputs.
workflow.run.failedA workflow run reaches FAILED.Workflow run state with error.

Setup

1

Create an event subscription

Call POST /event-subscriptions with:

  • endpointUrl - the HTTPS URL Plextera should POST events to.
  • eventTypes - one or more event types to subscribe to.
  • signingSecret - a secret used to sign deliveries.
  • filters - optional filters for workflow events, for example a specific workflow ID.
$curl -X POST https://api.plextera.com/api/public/v1/event-subscriptions \
> -H "Authorization: api-key YOUR_API_KEY" \
> -H "Content-Type: application/json" \
> -d '{
> "endpointUrl": "https://example.com/webhooks/plextera",
> "eventTypes": [
> "document-insights.extraction.completed",
> "document-insights.extraction.failed",
> "document-insights.extraction.rejected"
> ],
> "signingSecret": "whsec_your_secret"
> }'

The response omits filters when no filters are configured. Document Insights subscriptions usually do not need filters because the selected event types already define which extraction events are delivered.

2

Implement your webhook endpoint

Your endpoint must:

  • Accept POST requests with a JSON body.
  • Read the raw request body for signature verification.
  • Return a 2xx status after the event is accepted.
  • Handle duplicate deliveries safely.
3

Verify the signature

Verify the X-Plextera-Signature header before trusting the event payload.

Event payload model

Every event uses a common envelope:

1{
2 "eventId": "evt_01JY7M9QWBWCPMZK5QJ7RSE9P4",
3 "eventType": "document-insights.extraction.completed",
4 "occurredAt": "2026-04-07T10:22:00Z",
5 "apiVersion": "v1",
6 "data": { ... }
7}

The data field contains the event-specific payload. See the Event Reference for complete schemas and examples.

Delivery headers

Every webhook delivery includes:

HeaderDescription
X-Plextera-Delivery-IdUnique ID for this delivery attempt.
X-Plextera-Event-IdID of the event, stable across retry attempts.
X-Plextera-Event-TypeEvent type string.
X-Plextera-Event-Occurred-AtISO 8601 timestamp when the event occurred.
X-Plextera-Api-VersionAPI version, for example v1.
X-Plextera-SignatureHMAC-SHA256 signature for payload verification.

Verifying signatures

Each delivery is signed using the signingSecret you provided when creating the subscription. This confirms the delivery came from Plextera and that the payload was not modified.

Signature format:

X-Plextera-Signature: t=<unix timestamp>,v1=<hex hmac-sha256>

Verification steps:

  1. Extract t and v1 from the header.
  2. Construct the signed payload: <t>.<raw request body>.
  3. Compute HMAC-SHA256 using your signingSecret.
  4. Compare the computed signature with v1 using a constant-time comparison.
  5. Optionally reject old timestamps for replay protection.
1import hashlib
2import hmac
3import time
4
5
6def verify_signature(
7 payload: bytes,
8 header: str,
9 secret: str,
10 max_age_seconds: int = 300,
11) -> bool:
12 parts = dict(p.split("=", 1) for p in header.split(","))
13 timestamp = int(parts["t"])
14 signature = parts["v1"]
15
16 if abs(time.time() - timestamp) > max_age_seconds:
17 return False
18
19 signed = f"{timestamp}.".encode() + payload
20 expected = hmac.new(secret.encode(), signed, hashlib.sha256).hexdigest()
21 return hmac.compare_digest(expected, signature)

The signing secret is write-only. Plextera never returns it in API responses. Store it securely and rotate it by updating the subscription with a new signingSecret.

Retry and idempotency

  • Any 2xx response marks the delivery as successful.
  • Non-2xx responses trigger retries with exponential backoff.
  • The same eventId may be delivered more than once.
  • Your webhook handler should be idempotent. Store processed eventId values or use your own deduplication key.
  • If a document is reprocessed after a terminal state, a later terminal state can produce a new event.

Related reference

  • Event Reference - webhook payload schemas and examples
  • Event Subscriptions - create and manage subscriptions