VoiceThere

Inbound webhooks

Inbound webhooks let external systems POST HTTP requests to your VoiceThere project. The platform fans each request out to every readysession worker in your project namespace and delivers it to your agent's onWebhook handler with the raw body and inbound headers. Available on Advanced and Ultimate plans.

Webhook URL

Each project has a stable HTTPS endpoint (replace {projectId} with your project UUID):

https://webhooks.voicethere.io/{projectId}

Find the URL on the project Overview page under Runner settings when your plan includes inbound webhooks. The URL contains only the project id — treat verification in your agent as mandatory (see below).

Enable inbound webhooks

  • Dashboard: Project overview → Runner settings → Inbound webhooks toggle (webhooks_enabled).
  • CLI: voicethere projects settings set webhooks_enabled true
  • API: PATCH /projects/:projectId/runner-settings with { "key": "webhooks_enabled", "value": true }

The toggle is saved immediately. Routing uses your project's effective runner settings (tier grants merged with stored JSON). You do not need to redeploy to flip the setting, but you do need at least one live session worker (warm pool recommended) to accept traffic.

Rate limits and size

The public edge enforces per-project limits before fan-out:

  • 10 requests/second sustained, burst 20 — excess returns 429 with Retry-After
  • Request body cap 64 KiB — larger payloads return 413
  • POST only — other methods return 405

HTTP responses

  • 202 Accepted — at least one ready runner queued the webhook to your agent (partial pod failures still 202 when N≥1)
  • 403 Forbidden — effective webhooks_enabled is off (unknown project, Free/gated tier, or customer disabled)
  • 503 Service Unavailable — webhooks enabled but zero ready runners (scale up or enable warm pool)

Routing cache (up to 60 seconds)

The edge caches whether webhooks are enabled per project for up to 60 seconds. Enable/disable is usually immediate when settings change; in rare cases routing can lag for at most one TTL window. Plan agent idempotency accordingly.

No platform HMAC — verify in your agent

VoiceThere proxies method, path, all headers, and the exact request bytes into onWebhook. We do not sign, encrypt, or require a VoiceThere signature header. If you need authentication, verify a digest in your bundle using a secret stored as an encrypted AGENT_* project secret — same pattern as Stripe webhooks (sender signs; receiver verifies).

See Agent environment & secrets for storing verification keys.

Warm pool

Webhooks are delivered to live session workers. If your project scales to zero between sessions, callers receive 503 until a runner is ready. Enable warm pool on Advanced/Ultimate so at least one replica stays warm — see Runner settings.

Project Redis is not required

Fan-out uses the platform edge and session workers directly. You do not need Project Redis for webhook delivery. Use Redis only when your agent needs shared state across sessions (for example atomic counters) — the webhooks-redis agent template demonstrates both verification and Redis in one handler.

Agent templates

Agent logs

Each public webhook invocation emits one structured agent-log row (no session id). Browse invocations in Agent logs.

CLI examples

# List runner settings (look for webhooks_enabled)
voicethere projects settings list

# Enable inbound webhooks (Advanced/Ultimate)
voicethere projects settings set webhooks_enabled true

# Disable when you no longer need HTTP ingress
voicethere projects settings set webhooks_enabled false

Related

← All documentation