Webhook
Send events via HTTP POST requests to a URL endpoint.
Outpost supports two webhook modes:
- Default mode - Customizable headers and signature format
- Standard Webhooks mode - Follows the Standard Webhooks specification
Overview
When you publish an event:
json
Outpost sends an HTTP POST request with:
- Body: The event's
datafield as JSON - Headers: System metadata (
event-id,topic,timestamp) plus any event metadata, with a configurable prefix
Example request:
Configuration
Config
| Field | Type | Required | Description |
|---|---|---|---|
config.url | string | Yes | The URL to send events to |
config.custom_headers | string | No | JSON object of custom headers to include |
Credentials
| Field | Type | Required | Description |
|---|---|---|---|
credentials.secret | string | No | Signing secret (auto-generated if not provided) |
credentials.previous_secret | string | No | Previous secret during rotation |
credentials.previous_secret_invalid_at | string | No | RFC3339 timestamp when previous secret expires |
If secret is not provided, one will be auto-generated. Tenants cannot modify secrets directly - they can only trigger rotation.
Example
sh
Secret Rotation
Secret rotation allows you to change the signing secret without downtime. During the rotation window, both the old and new secrets are valid for signature verification.
To rotate a secret, set rotate_secret to true when updating a destination:
sh
When rotation is triggered:
- The current secret becomes
previous_secret - A new secret is generated
- The previous secret remains valid for 24 hours by default
- Both secrets are included in the signature header during the rotation window
To customize the rotation window, set previous_secret_invalid_at:
sh
Default Mode
In default mode, Outpost provides a customizable webhook implementation.
Headers
Outpost adds headers using the configured prefix (default x-outpost-):
| Header | Source | Description |
|---|---|---|
x-outpost-id | System | The unique event ID |
x-outpost-timestamp | System | Event timestamp (Unix) |
x-outpost-topic | System | The event topic |
x-outpost-signature | System | HMAC-SHA256 signature |
x-outpost-{key} | Event | Any metadata from the published event's metadata field |
Signature
The signature is computed over the timestamp and request body:
The signature header value follows the format: t=${timestamp},v0=${signature}
Verifying Signatures
To verify webhook requests:
- Extract the timestamp and signature from the
x-outpost-signatureheader - Compute the expected signature using your secret
- Compare signatures using a constant-time comparison
- Optionally, reject requests with old timestamps to prevent replay attacks
Operator Configuration
Operators can customize webhook behavior via environment variables.
Header Configuration
| Environment Variable | Default | Description |
|---|---|---|
DESTINATIONS_WEBHOOK_HEADER_PREFIX | x-outpost- | Prefix for all webhook headers |
DESTINATIONS_WEBHOOK_DISABLE_EVENT_ID_HEADER | false | Disable the event ID header |
DESTINATIONS_WEBHOOK_DISABLE_TIMESTAMP_HEADER | false | Disable the timestamp header |
DESTINATIONS_WEBHOOK_DISABLE_TOPIC_HEADER | false | Disable the topic header |
DESTINATIONS_WEBHOOK_DISABLE_SIGNATURE_HEADER | false | Disable the signature header |
Signature Configuration
| Environment Variable | Default | Description |
|---|---|---|
DESTINATIONS_WEBHOOK_SIGNATURE_ALGORITHM | hmac-sha256 | Signature algorithm |
DESTINATIONS_WEBHOOK_SIGNATURE_ENCODING | hex | Signature encoding (hex or base64) |
DESTINATIONS_WEBHOOK_SIGNATURE_VALUE_TEMPLATE | {{.Timestamp.Unix}}.{{.Body}} | Template for the value being signed |
DESTINATIONS_WEBHOOK_SIGNATURE_HEADER_TEMPLATE | t={{.Timestamp.Unix}},v0={{.Signatures | join ","}} | Template for signature header value |
See the migration guide for common customization patterns.
Standard Webhooks Mode
Standard Webhooks mode follows the Standard Webhooks specification, providing a standardized format for webhook signatures and headers used by many webhook providers.
To enable Standard Webhooks mode, set:
Headers
| Header | Source | Description |
|---|---|---|
webhook-id | System | The unique event ID |
webhook-timestamp | System | Event timestamp (Unix) |
webhook-signature | System | Signature in v1,<base64> format |
webhook-{key} | Event | Any metadata from the published event's metadata field |
Signature
The signature follows the Standard Webhooks specification:
Verifying Signatures
Use the official Standard Webhooks SDK to verify signatures. SDKs are available for multiple languages including JavaScript, Python, Go, Ruby, and more.
Secret Format
Standard Webhooks secrets use the format whsec_<base64>, which is automatically generated when creating a destination.
Operator Configuration
| Environment Variable | Default | Description |
|---|---|---|
DESTINATIONS_WEBHOOK_MODE | default | Set to standard to enable Standard Webhooks mode |
DESTINATIONS_WEBHOOK_HEADER_PREFIX | webhook- | Prefix for Standard Webhooks headers |
Custom Headers
Tenants can add custom HTTP headers to webhook requests. This is useful for authentication, routing, or passing additional metadata to their endpoint.
sh
Header Name Requirements
- Must start with a letter or digit
- Can contain letters, digits, underscores (
_), and hyphens (-)
Reserved Headers
The following headers cannot be overridden:
content-typecontent-lengthhostconnectionuser-agent
Operator Configuration
Custom headers are disabled in the tenant portal by default. To enable, set PORTAL_ENABLE_WEBHOOK_CUSTOM_HEADERS=true.