Webhooks
Register endpoints and verify signed event delivery.
/api/v1/webhooksList Webhooks
List registered webhooks (secrets are not returned).
Response 200
{
"webhooks": [
{
"id": "uuid",
"url": "https://example.com/webhook",
"events": ["project.ready"],
"created_at": "..."
}
]
}/api/v1/webhooksRegister Webhook
Register a webhook URL to receive signed event notifications.
Request body
{
"url": "https://example.com/webhook",
"events": ["project.ready", "project.failed"]
}Response 201
{
"id": "uuid",
"url": "https://example.com/webhook",
"events": ["project.ready", "project.failed"],
"secret": "abc123...",
"created_at": "..."
}Store the secret now - it is shown only once. Use it to verify X-SparkVox-Signature on incoming requests.
/api/v1/webhooks/:idDelete Webhook
Remove a webhook. Returns 200 with { "deleted": true }.
Webhook Events
SparkVox sends a signed POST to your endpoint when events occur.
Request format
POST https://example.com/webhook
Content-Type: application/json
X-SparkVox-Signature: <hmac-sha256-hex>
X-SparkVox-Event: project.readySignature verification
const crypto = require("crypto");
function verifySignature(body, signature, secret) {
const expected = crypto
.createHmac("sha256", secret)
.update(body, "utf8")
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}project.ready
Fired when all posts have been generated for a project.
{
"event": "project.ready",
"data": {
"project_id": "uuid",
"title": "My Episode",
"post_count": 12,
"posts_url": "https://app.sparkvox.io/api/v1/projects/<id>/posts"
},
"timestamp": 1748790000000
}project.failed
Fired when a project fails at any pipeline stage (ingest, transcription, billing, generation). Processing time is refunded automatically when a charged project fails.
{
"event": "project.failed",
"data": {
"project_id": "uuid",
"error": "insufficient_credits"
},
"timestamp": 1748790000000
}data.error may be insufficient_credits (not enough processing time), billing_error, or a truncated pipeline error message (max 500 characters).
v1 delivery: Fire-and-forget. No automatic retry. If your endpoint returns a non-2xx status the event is dropped.