Secure your webhook endpoints by verifying that each request genuinely came from Catena and hasn’t been tampered with. Every webhook includes cryptographic signatures and comprehensive headers for authentication, tracking, and event routing.Documentation Index
Fetch the complete documentation index at: https://docs.catenatelematics.com/llms.txt
Use this file to discover all available pages before exploring further.
Request Headers
Every webhook request includes HTTP headers for security verification, event metadata, and delivery tracking. Here’s what a typical webhook request looks like with all headers included:Header Reference
| Header | Example Value | Description |
|---|---|---|
X-Catena-Signature | 2jSwOn+crDEbShY66aX1xn6uQXpAU9Ufw= | Base64-encoded HMAC-SHA256 signature for verifying request authenticity. Computed as HMAC_SHA256(webhook_secret, timestamp + "." + uncompressed_payload). Always validate before processing events. |
X-Catena-Timestamp | 2024-11-28T10:30:00+00:00 | RFC 3339 formatted UTC timestamp when the event was sent. Used for signature computation and replay attack prevention. Reject requests older than 5 minutes. |
X-Event-Type | vehicle.modified | The type of event being delivered, matching the event_name from your webhook subscription. Use for routing events to appropriate handlers. |
X-Schema-Version | 1.2 | The version of the event payload schema. Monitor for schema updates to handle changes gracefully. |
X-Source | catena-notifications | Identifies the Catena service that generated the event. Useful for logging and debugging. |
X-Request-ID | 62cb8fea-e017-4b08-86b7-4469fa872b91 | Unique identifier for this specific delivery attempt. Changes with each retry. Use for duplicate detection. |
X-Webhook-ID | 247b2dea-a030-48b7-9a05-ee33c1b6ab0a | The unique identifier of your webhook subscription. Use when multiple webhooks share the same endpoint. |
X-Delivery-Attempt | 1, 2, 3 | The delivery attempt number (starts at 1, increments with retries). Use for monitoring delivery reliability. |
Content-Type | application/json | Request body format (always JSON). |
Content-Encoding | gzip | Payload compression format. Event payloads are always gzip-compressed to reduce bandwidth usage. |
User-Agent | Catena-Webhook | Identifies requests as coming from Catena webhooks. |
Accept | application/json | Expected response format. |
Signature Verification
Catena signs every webhook using HMAC-SHA256 to ensure authenticity. The signature covers the timestamp and request body, preventing tampering and replay attacks.Signing Key Management
When creating a webhook subscription, you can either provide your own signing key or let Catena generate one:Provide Your Own Key
Provide Your Own Key
Include your secret key in the subscription request for full control over key management.
Catena-Generated Key
Catena-Generated Key
Omit the
secret field and Catena will generate a secure key returned once in the creation response.The generated secret is shown in full only in the initial creation response. In all subsequent API responses, the secret is masked as ***** for security.Key Rotation
Key Rotation
If you lose your key or need to rotate it for security, use the webhook update endpoint to set a new secret.
How Signatures Work
Each webhook includes two security headers:X-Catena-Signature— Base64-encoded HMAC-SHA256 digestX-Catena-Timestamp— RFC 3339 timestamp (e.g.,2024-01-15T10:30:00+00:00)
Verification Steps
Implement signature verification in four steps:Extract headers and body
Get the signature headers and raw request body:
X-Catena-Timestamp— The timestamp used in signature computationX-Catena-Signature— The expected signature- Uncompressed payload — Decompress the gzipped request body to get the JSON string
Check timestamp freshness
Parse the timestamp and verify it’s recent:
- Parse
X-Catena-Timestampas RFC 3339 / ISO 8601 - Reject requests older than 5 minutes to prevent replay attacks
- Account for clock skew between servers
Compare signatures securely
Use constant-time comparison to prevent timing attacks:
- Compare
X-Catena-Signaturewith your computed signature - Use timing-safe comparison (e.g.,
hmac.compare_digestin Python) - Respond with 401 Unauthorized if verification fails
- Respond with 400 Bad Request if headers are missing/malformed
Implementation Example
Python
Security Best Practices
Always verify signatures
Never process webhook events without signature verification. This protects against spoofing and tampering.
Use constant-time comparison
Prevent timing attacks by using constant-time comparison functions (
hmac.compare_digest, crypto.timingSafeEqual).Reject stale requests
Check timestamp freshness and reject requests older than 5 minutes to prevent replay attacks.
Always decompress payload
Webhooks are always gzip-compressed. Decompress the raw bytes to get the JSON string for signature verification.
Store secrets securely
Keep webhook secrets in environment variables or a secrets manager, never in code.
Implement rate limiting
Protect your endpoint from abuse with rate limiting, even for authenticated requests.
Log validation failures
Monitor and alert on signature validation failures to detect potential attacks.
Use HTTPS only
Configure webhook URLs with HTTPS to encrypt data in transit. Catena rejects HTTP endpoints.
Troubleshooting
Signature verification always fails
Signature verification always fails
Common causes:
- Using parsed JSON instead of uncompressed payload string
- Not decompressing the payload before verification
- Incorrect webhook secret
- Character encoding issues (ensure UTF-8)
Intermittent verification failures
Intermittent verification failures
Common causes:
- Clock skew between servers
- Timestamp tolerance too strict
- Network delays causing stale timestamps
Missing headers
Missing headers
Common causes:
- Proxy or load balancer stripping headers
- Case-sensitive header lookups
- Framework normalizing header names
x-catena-signature) depending on your framework.