Agent skill
Sovos Webhooks Skill
Receive and verify Sovos e-invoicing (Indirect Tax API) webhooks delivered through Svix. Use when setting up a Sovos webhook handler, debugging svix-id / svix-timestamp / svix-signature verification, configuring the Svix Consumer App Portal, or handling Sovos document notifications by eventType such as document.received, document.completed, workflow.completed, and system.error.
Install this skill
npx skills add hookdeck/webhook-skills --skill sovos-webhooks
Sovos pushes Indirect Tax API (e-invoicing) notifications to your ERP endpoint through Svix. Svix signs each webhook, retries failed deliveries, and hosts the Consumer App Portal where you add endpoints, copy the signing secret, and inspect delivery logs. This skill covers the Indirect Tax API / e-invoicing webhooks only; other Sovos products are out of scope.
When to Use This Skill
- How do I receive Sovos e-invoicing webhooks?
- How do I verify Sovos webhook signatures (
svix-signature)? - How do I handle a Sovos
document.receivednotification? - Why is my Sovos webhook signature verification failing?
- Where do I find the Sovos webhook signing secret (Svix Consumer App Portal)?
- How do I download the application response from
contentUrl?
Verification (core)
Sovos does not define its own signature scheme: its docs tell you to verify with the Svix library or Svix's manual procedure. The header names and the whsec_ secret format below come from Svix's verification guide, which Sovos links to; Sovos's own pages don't restate them. Each request carries three headers:
svix-id: msg_2b1c... # unique message id
svix-timestamp: 1770290583 # Unix seconds
svix-signature: v1,g0hM9SsE... # space-delimited "v1,<base64 sig>" entries
Signed content is ${svix-id}.${svix-timestamp}.${raw_, HMAC-SHA256 keyed with the base64-decoded bytes after the whsec_ prefix, base64-encoded. The official svix SDK (Node and Python) does all of this, including the 5-minute timestamp tolerance, rotation (multiple signatures), and constant-time compare:
import { Webhook } from 'svix';
const wh = new Webhook(process.env.SOVOS_WEBHOOK_SECRET); // "whsec_..."
wh.verify(rawBody, { // rawBody: the raw Buffer/string, never re-serialized JSON
'svix-id': req.headers['svix-id'],
'svix-timestamp': req.headers['svix-timestamp'],
'svix-signature': req.headers['svix-signature'],
}); // throws WebhookVerificationError on failure; returns undefined in svix 2.x
const notification = JSON.parse(rawBody.toString('utf8'));
// notification.eventType === 'document.received', notification.metadata.documentId, ...
Python uses the same API: from svix.webhooks import Webhook and Webhook(secret).verify(body_. For the manual (no-SDK) algorithm, see references/verification.md.
For complete handlers with tests, see examples/express/, examples/nextjs/, examples/fastapi/.
Common Event Types
The event type is the top-level eventType field (not type). You choose which events are sent on the Sovos side (Compliance Network UI or POST /v2/configurations/workspaces/settings); the Svix portal cannot add or filter events. Event names that appear in Sovos's documentation:
eventType | When it is sent |
|---|---|
document.received | A document notification was received during processing (the documented payload example) |
document.completed | A document finished its lifecycle |
workflow.completed | A processing workflow for a document completed |
system.error | Processing failed with a system error |
Sovos does not publish a full catalog on the webhooks pages, so keep a default branch for event types you have not mapped. See references/overview.md for the payload fields.
Environment Variables
# Endpoint signing secret from the Svix Consumer App Portal (starts with whsec_)
SOVOS_WEBHOOK_SECRET=whsec_xxxxx
Local Development
# Start tunnel (no account needed)
npx hookdeck-cli listen 3000 sovos --path /webhooks/sovos
Add the tunnel URL as an endpoint in the Svix Consumer App Portal, then use the portal's Testing tab to send an example event.
Reference Materials
- references/overview.md - How Sovos notifications work, event types, payload fields
- references/setup.md - Configure the ERP system, webhook communication method, and Consumer App Portal
- references/verification.md - Svix signature verification (SDK and manual) and gotchas