Call webhooks
When a call reaches one of your numbers, HCC POSTs a signed request to the number's call webhook URL. Reply with Call Instructions. Hono on Cloudflare Workers:
import { Hono } from 'hono';
import { SIGNATURE_HEADER, instructions as i, respond, webhooks } from '@hcc/sdk';
type Env = { HCC_CALL_WEBHOOK_SECRET: string };
const app = new Hono<{ Bindings: Env }>();
app.post('/hcc/call', async (c) => {
const body = await c.req.text(); // raw body: needed for the signature
const ok = await webhooks.verify({
secret: c.env.HCC_CALL_WEBHOOK_SECRET,
body,
signature: c.req.header(SIGNATURE_HEADER),
});
if (!ok) return c.text('invalid signature', 401);
return respond(
i.say('Thanks for calling Acme.'),
i.gather({ input: ['dtmf'], numDigits: 1, prompt: i.say('Press 1 for sales.'), tag: 'menu' }),
i.connectAgent('agt_123'),
);
});
export default app;respond(...) returns a JSON Response with { instructions }; use instructionsBody(...) if your framework wants the plain object. Builders validate their input and throw on invalid values (empty text, non-E.164 numbers, out-of-range timeouts).
Available builders: say, play, pause, connectAgent, dial, enqueue, gather, record, hangup.
What a caller enters on a gather shows on the call's timeline and in its API record. For card numbers, PINs and the like, pass sensitive: true: your flow or webhook still gets the input, and we keep only how much was entered ("4 digits entered"). A webhook delivery of a sensitive gather can't be resent, because its event isn't kept. Anything your own handler stores or logs is yours to protect.