Skip to content

Phone calls

A phone call runs exactly like a browser session: the same tools, the same state, the same prompt. Three steps put a published agent on a number.

import { agent } from "@alexkroman1/aai";
export default agent({
name: "Support Line",
telephony: ["twilio"],
});

The default is empty, so an agent that names no carrier refuses phone calls.

aai publish prints one webhook URL per carrier you declared, with the ?carrier= parameter already filled in:

https://<your-agent-url>/phone?carrier=twilio

Paste that into the phone number’s incoming-call webhook field, in your carrier’s console.

aai publish --json carries the same lines in its output field, so a script that publishes does not have to re-derive them.

Signature verification turns on when the agent has the carrier’s own secret. Set TWILIO_AUTH_TOKEN (or TELNYX_PUBLIC_KEY) as a secret and every request is checked:

Terminal window
printf %s "$TWILIO_AUTH_TOKEN" | aai secret put TWILIO_AUTH_TOKEN

Set neither and the route is as open as any other — anyone who learns the URL can make your agent answer. See Publish for how secrets work.

That is the whole setup. What follows is reference.

Value Result
["twilio"] Serves Twilio, refuses Telnyx
["twilio", "telnyx"] Serves both
true Serves every carrier this build ships a codec for
false, [], or absent Does not serve the route at all

The route assumes Twilio when ?carrier= is absent, so a Telnyx number configured without it is verified against the wrong scheme and every call is refused with 403 Invalid webhook signature — a failure that names the signature rather than the missing parameter.

The platform cannot infer the carrier for you, because it stores no description of your agent. That is why the CLI, which has your telephony declaration in hand, is what prints these URLs.

It answers with the markup that opens the media stream. That part is not something you configure.

A declared carrier whose secret is missing from the env being uploaded is warned about by name at deploy time, beside the provider-credential warning:

telephony declares telnyx but TELNYX_PUBLIC_KEY is not set — the telnyx webhook
will be served with signature verification OFF, so anyone who knows the URL can
start a call. Declare TELNYX_PUBLIC_KEY in .env and redeploy (already set on
the platform with `aai secret put`? then this is already handled).

It is a warning rather than a refusal, for the same reason the credential check is. The CLI sees the env it is about to upload, and cannot see what an earlier aai secret put already stored against the agent — so a secret the platform holds looks missing from here.

Worth knowing: verification is on for the whole route as soon as either secret is set. A call naming a carrier whose secret is missing is then refused rather than let through unverified.