Overview
Receive webhook events from external services and convert them into provenance interactions automatically.
Inbound Webhooks let you receive events from external services — Stripe, GitHub, Twilio, or any system that sends webhooks — and automatically convert them into provenance interactions. No custom integration code required.
How it works
External Service → Webhook URL → Source Validation → Mapping Match → Interaction Created- An external service sends a webhook to your Provenance inbound URL
- The source validates the request (signature verification, schema validation)
- The mapping matches the payload against filter conditions and determines which resource type + action to use
- Field mappings extract data from the payload into the interaction metadata
- A provenance interaction is created automatically
Key concepts
Sources
A source represents an external service sending webhooks. Each source has:
- A unique mnemonic (e.g.
STRIPE,GITHUB) - An origin — interactions from this source are tagged with this origin
- Signature verification — HMAC-SHA256, HMAC-SHA1, or plain comparison
- Payload schema — optional AJV schema to validate incoming payloads at the source level
- A webhook URL — unique per source, includes your tenant slug
Mappings
A mapping defines how a specific type of webhook payload becomes a provenance interaction. Each mapping belongs to a source and specifies:
- Resource type and action — what kind of interaction to create
- Filter conditions — match specific payloads (e.g. only
checkout.session.completedevents) - Schema validation — optional AJV schema for mapping-level validation, with support for targeting a nested sub-object via
schemaRootPath - Field mappings — extract values from the payload into the interaction metadata
- Resource ID path — which payload field to use as the resource ID
- Metadata paths — map payload fields to interaction metadata like
userId,sessionId,uowId - Priority — when multiple mappings match, the highest priority wins
Processing pipeline
When a webhook arrives:
- Source lookup — resolve the source from the URL (by ID or mnemonic)
- Signature verification — validate the request signature using the source's secret and algorithm
- Source schema validation — if the source has a payload schema, validate the raw payload
- Mapping selection — find all active mappings for this source, filter by conditions, pick the highest priority match
- Mapping schema validation — if the matched mapping has a payload schema, validate (optionally against a sub-object via
schemaRootPath) - Deduplication — if the mapping has an idempotency path, check for duplicate interactions
- Interaction creation — extract fields, build the interaction, and insert it
Webhook URLs
Each source gets two webhook URLs:
# By source ID
POST /api/inbound/:tenantSlug/:sourceId
# By mnemonic (human-readable)
POST /api/inbound/:tenantSlug/by-mnemonic/:mnemonicBoth are unauthenticated — security is handled by signature verification.
Sync mode (development)
For local testing, append ?sync=true to process the webhook synchronously instead of through the queue:
POST /api/inbound/:tenantSlug/:sourceId?sync=trueThis is disabled in production (NODE_ENV=production).
API reference
| Method | Endpoint | Description |
|---|---|---|
GET | /api/inbound-sources | List all sources |
GET | /api/inbound-sources/:id | Get source by ID |
POST | /api/inbound-sources | Create source |
PUT | /api/inbound-sources/:id | Update source |
DELETE | /api/inbound-sources/:id | Delete source |
GET | /api/inbound-mappings | List all mappings |
GET | /api/inbound-mappings/:id | Get mapping by ID |
POST | /api/inbound-mappings | Create mapping |
PUT | /api/inbound-mappings/:id | Update mapping |
DELETE | /api/inbound-mappings/:id | Delete mapping |
POST | /api/inbound-mappings/:id/test | Test mapping with sample payload |
POST | /api/inbound/:slug/:sourceId | Receive webhook (by source ID) |
POST | /api/inbound/:slug/by-mnemonic/:mnemonic | Receive webhook (by mnemonic) |