Place AI calls and manage Astra via the API
The API can configure and publish Astra (your AI agent), connect a number to it, and have it place outbound calls: POST /v1/api/calls makes your published agent dial a number, hold the conversation, and log the call — with recording, transcript, and summary — on the contact's timeline in your inbox, billed in AI credits exactly like an inbound AI-answered call.
Before you start
- Your API key needs the right scopes — chips in Settings → Developer API: Manage AI agent (
agent:manage) for agent config and number routing, and Place AI calls (calls:place) for outbound calls. Full-access keys include both. See Get your Ody API key. - Outbound calls require an active plan, a published and enabled agent, and at least one active number in your workspace.
- Credits work exactly as usual: 100 credits per AI-answered call, calls under 15 seconds free, and every plan includes 1,000 credits a month. See Astra credits and usage.
Configure and publish your agent
GET /v1/api/agent returns the agent's config plus your current-cycle credit usage — handy for checking budget before a batch of calls. PATCH /v1/api/agent updates it: name, greeting, tone, voice, language, timezone, inHoursAction/offHoursAction (agent, voicemail, app, or forward), enabled, and jobs. Only the fields you send change, except jobs, which is replaced wholesale when supplied:
curl -X PATCH https://api.ody.co/v1/api/agent \
-H "Authorization: Bearer ody_live_…" \
-H "Content-Type: application/json" \
-d '{
"name": "Front Desk",
"greeting": "Thanks for calling Acme Plumbing!",
"tone": "Friendly",
"jobs": [{"name": "Take a message", "instructions": "Collect the name, number, and reason for calling."}]
}'
Changes save as a draft — the same draft you'd see on the AI agent screen in the app. Push it live with:
curl -X POST https://api.ody.co/v1/api/agent/publish \
-H "Authorization: Bearer ody_live_…"
Connect a number to the agent
POST /v1/api/numbers/{number}/connect routes one of your numbers to the agent so it answers inbound calls (URL-encode the + as %2B):
curl -X POST "https://api.ody.co/v1/api/numbers/%2B15125550123/connect" \
-H "Authorization: Bearer ody_live_…"
To route it back to your team, use …/disconnect with a mode of app (ring your team — the default), voicemail, or forward (with a forwardTo number):
curl -X POST "https://api.ody.co/v1/api/numbers/%2B15125550123/disconnect" \
-H "Authorization: Bearer ody_live_…" \
-H "Content-Type: application/json" \
-d '{"mode":"app"}'
Place an outbound AI call
POST /v1/api/calls has your published agent dial out and hold the conversation:
curl https://api.ody.co/v1/api/calls \
-H "Authorization: Bearer ody_live_…" \
-H "Content-Type: application/json" \
-d '{"to":"+15125550199"}'
tois required (E.164).fromis optional — Ody prefers your agent-connected number, then your first active number; passfromto pick a specific line you own.- International destinations follow your workspace's usual international-calling rules — see International calling and limits.
- When the call ends, it appears on the contact's timeline in your inbox with a recording, transcript, and summary — the same "AI agent handled this call" card as an inbound AI call.
- Billing: 100 credits when the call is answered, free under 15 seconds — and a call that's never answered is always free.
You can take over any time
Anything done through the API is your real account state — not a separate developer sandbox. The agent your code publishes is the one on the AI agent screen; the number it connects is in Settings → Numbers; the calls it places land in your shared inbox. That means you can jump in whenever you want: edit the greeting in the app, reply in a thread yourself, or click a number's routing chips to send calls back to your team — no API involved.
From an AI assistant (MCP)
Connected AI assistants get the same powers as MCP tools: get_agent, configure_agent (pass publish: true to go live in one step), connect_agent_to_number, and place_call. See Connect AI tools with MCP.
Test mode
With an ody_test_… key, POST /calls returns a simulated call (a sim_… id, nothing dialed, no credits used) and POST /agent/publish is simulated (your config stays a draft). Draft saves via PATCH /agent are real on both key types. See Build safely with test mode.
Related articles
Frequently asked questions
What do outbound AI calls cost?
The same as inbound AI-answered calls: 100 AI credits per answered call, and calls under 15 seconds are free. A call that's never answered costs nothing.
What's required before I can place a call?
An active plan, a published and enabled AI agent, and at least one active number. Ody dials from your agent-connected number unless you pass a from number you own.
Can I take over from the agent?
Any time. Everything the API changes is the same agent, numbers, and threads you see in the app — open it to edit the agent, reply in a thread, or route the number back to your team.