SDKDeployment

Deployment

Deploy to Vercel (fastest)

npm install -g vercel
vercel

Then in the Vercel dashboard → Project Settings → Environment Variables, add all five values from .env.example. Hit redeploy.

Your webhook endpoint will live at:

https://<your-deployment>.vercel.app/api/webhooks/ear3

Go back to Settings → Webhooks at app.ear3.ai and update the endpoint URL to that.

Receive webhooks in local development

Ear3 needs a publicly reachable URL to deliver webhooks. localhost won’t work directly. Two reliable options:

Option A — ngrok

ngrok http 3000

Copy the https://*.ngrok-free.app URL it prints. Register it as your webhook endpoint at app.ear3.ai. Restarting ngrok regenerates the URL — update the endpoint each time.

Option B — Vercel preview deploy

Push your branch — Vercel will auto-create a preview deployment at https://<branch>-<project>.vercel.app. Use that URL as the webhook endpoint. Subsequent pushes update the same preview.

Environment variable checklist

VariableWhereWhy
NEXT_PUBLIC_EAR3_VOICE_INTERVIEWER_KEYServer + browserUsed by <Ear3Interview> in the client bundle
NEXT_PUBLIC_EAR3_INTERVIEW_IDServer + browserSame
EAR3_CONFIG_CLI_KEYServer onlyUsed by @ear3/server for retrieve / admin
EAR3_WEBHOOK_SECRETServer onlyUsed by constructEvent to verify signatures
NEXT_PUBLIC_EAR3_BASE_URLOptionalOverride the Ear3 API base (self-host or staging)
EAR3_BASE_URLOptionalSame for server-side

The NEXT_PUBLIC_ prefix is a Next.js convention — anything without it stays server-side. Never add the NEXT_PUBLIC_ prefix to sk_ or whsec_ values; doing so would expose them to the browser.

Production checklist

Before flipping the DNS:

  • Created live mode API keys (pk_live_…, sk_live_…, whsec_…) — not test mode
  • Webhook endpoint URL points at your production domain
  • interview.completed is subscribed
  • Verified end-to-end: complete a test interview in incognito, confirm your webhook handler runs and updates the user record
  • .env.local is .gitignored (it already is in this template)
  • No sk_ or whsec_ value appears in your committed code or any NEXT_PUBLIC_* variable
  • Sentry / your error tracker captures SignatureVerificationError so you can investigate any forged or stale deliveries

Other hosts

The template is a vanilla Next.js 15 app. It works on:

  • Cloudflare Pagesnpm run build + wrangler pages deploy .next
  • Railway / Render / Fly — bring your own Dockerfile
  • Self-hosted Nodenpm run build && npm start

In all cases the same env vars apply, and your webhook URL is wherever your /api/webhooks/ear3 is reachable from the public internet.


Built by Ear3 — voice interviews for any app.
⌘/