通过 AgentLine 电话 API 实现拨打电话、查看接收的短信、配置号码、管理客服和计费追踪,适用于用户请求呼叫时使用。
Give your AI agent a real phone number and voice calls — no servers, no webhooks, no infrastructure.
Follow these steps IN ORDER when setting up AgentLine for the first time:
Check for AGENTLINE_API_KEY (starts with sk_live_) — this is required.
Check for AGENTLINE_AGENT_ID (starts with agt_) — this is optional.
POST /v1/agents with {"name": "My Agent"}. Save the returned agent ID.Ask for area code and provision the number — Always ask the human:
"What area code would you like for your phone number? (e.g. 212 for NYC, 415 for SF, 313 for Detroit)"
POST /v1/numbers with {"agent_id": "...", "area_code": "XXX"}Ask for voice preference — Always ask the human:
"Would you like your agent to have a male or female voice?"
voice_id to "female-1" (or "female-2" for warmer tone)voice_id to "male-1"PATCH /v1/agents/$AGENTLINE_AGENT_ID with {"voice_id": "chosen_preset"}female-1, female-2, male-1 — or any Cartesia voice UUIDStart the background event poller — This is MANDATORY. Write the polling script (see Events Mailbox section below) to a scratch file and launch it as a background command. Without this, you will miss all inbound calls and SMS messages.
⚠️ Do NOT skip ANY steps. Steps 1-4 set up the agent. Step 5 keeps it alive and aware of incoming calls/texts.
terminal(background=true)⚠️ Do NOT skip steps or change the order. The human should have a working agent with their chosen area code number, voice, and running event poller by the end.
Every request: Authorization: Bearer $AGENTLINE_API_KEY + Content-Type: application/json
Base URL: https://api.agentline.cloud
AgentLine runs in Hosted Mode — the server runs the AI voice conversation autonomously. You create a call, the AI handles it, you retrieve the transcript afterwards.
system_prompt field in POST /v1/calls. Overrides default for that call only.PATCH /v1/agents/{agent_id}. Used for all inbound calls and outbound calls without a dynamic prompt.⚠️
system_promptis a FULL REPLACE, not append. The voice AI has no memory between calls — put everything (personality, instructions, current context) in the prompt. Update it whenever your context changes.
bash
curl -X POST $AGENTLINE_URL/v1/calls \
-H "Authorization: Bearer $AGENTLINE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"agent_id": "$AGENTLINE_AGENT_ID", "to_number": "+1XXXXXXXXXX", "system_prompt": "...", "initial_greeting": "...", "voice_id": "female-1"}'
FieldRequiredDescriptionagent_idYesYour agent IDto_numberYesE.164 phone number to callsystem_promptNoDynamic prompt for this call only (overrides default)initial_greetingNoWhat the agent says first when the person picks upvoice_idNo"female-1", "female-2", "male-1", or Cartesia UUID
After every outbound call: Poll GET /v1/calls/<call_id> every ~10s until status=completed, then GET /v1/calls/<call_id>/transcript. Summarize and share with human. Never consider a call "done" without the transcript.
If you get 400 "Agent has no active phone number", provision one first.
POST /v1/calls/<call_id>/hangup
GET /v1/calls/<call_id>/transcript — Returns [{role, text, timestamp}, ...]
Events are pushed when someone calls or texts your agent's number. You MUST poll regularly.
Event types: call.received (inbound call started), call.completed (call ended, includes transcript), sms.received (inbound SMS)
⚠️ Do NOT use
schedule/cron to poll. Use the background script approach — it only wakes you when events exist.
Setup: Write the polling script to a scratch file, then launch as a background command with WaitMsBeforeAsync=500.
Windows (PowerShell):
powershell
param([string]$ApiKey, [string]$BaseUrl = "https://api.agentline.cloud", [int]$Interval = 50)
$headers = @{ "Authorization" = "Bearer $ApiKey" }
while ($true) {
try {
$r = Invoke-RestMethod -Uri "$BaseUrl/v1/events/peek" -Headers $headers -Method Get -ErrorAction Stop
if ($r.count -gt 0) { Write-Output "AGENTLINE_EVENTS_FOUND: $($r.count) pending event(s). Call GET /v1/events to consume." }
} catch {
if ($_.Exception.Response.StatusCode -eq 401) { Write-Output "AGENTLINE_AUTH_ERROR"; break }
}
Start-Sleep -Seconds $Interval
}
macOS/Linux (Bash):
bash
#!/usr/bin/env bash
set -uo pipefail
API_KEY="$1"; BASE_URL="${2:-https://api.agentline.cloud}"; INTERVAL="${3:-50}"
while true; do
RESP=$(curl -s -w "\n%{http_code}" "$BASE_URL/v1/events/peek" -H "Authorization: Bearer $API_KEY" 2>/dev/null) || { sleep "$INTERVAL"; continue; }
CODE=$(echo "$RESP" | tail -1); BODY=$(echo "$RESP" | sed '$d')
[ "$CODE" = "401" ] && { echo "AGENTLINE_AUTH_ERROR"; exit 1; }
[[ "$CODE" != 2* ]] && { sleep "$INTERVAL"; continue; }
COUNT=$(echo "$BODY" | grep -oP '"count"\s*:\s*\K[0-9]+' 2>/dev/null || echo "0")
[ "$COUNT" -gt 0 ] && echo "AGENTLINE_EVENTS_FOUND: $COUNT pending event(s). Call GET /v1/events to consume."
sleep "$INTERVAL"
done
When notified with AGENTLINE_EVENTS_FOUND: Call GET /v1/events to consume, process each event, report to human.
GET /v1/events — returns events oldest-first, auto-deleted after retrievalGET /v1/events/peek?agent_id=agt_xxx or ?event_type=call.completed or ?event_type=sms.receivedEach event contains: event_id, agent_id, event_type, and a payload with call/SMS details. call.completed payloads include from_number, to_number, duration_seconds, and full transcript array. sms.received payloads include from_number, body, and media_url.
GET /v1/calls?limit=20 or GET /v1/calls?status=completed&limit=10
GET /v1/calls/<call_id>
⚠️ SMS sending is NOT enabled. Do NOT attempt outbound SMS/MMS.
Inbound SMS arrives as sms.received events in the Events Mailbox. View message history: GET /v1/messages?limit=20
PATCH /v1/agents/$AGENTLINE_AGENT_ID with any of:
FieldDescriptionsystem_promptFull instructions + current context for voice AIinitial_greetingWhat the agent says when answering inbound callsnameDisplay namevoice_id``"female-1", "female-2", "male-1", or Cartesia UUIDmodel_tier``"turbo", "balanced", or "max"
GET /v1/agents/$AGENTLINE_AGENT_IDGET /v1/agentsPriority (highest wins): per-call → per-agent → per-account
GET /v1/voicesPATCH /v1/account/voice with {"voice_id": "female-1"}GET /v1/account/voiceDELETE /v1/account/voiceEach agent needs one phone number. Only US numbers supported. $2.00 per number.
POST /v1/numbers with:
FieldRequiredDescriptionagent_idYesAgent to attach tocountryYesMust be "US"``area_codeNoPreferred 3-digit area code (e.g. "212", "313"). Always ask the user!number_typeNo"local" or "tollfree" (default: local)
If no numbers are available for the requested area code, the API returns an error — ask the user for a different area code.
GET /v1/numbers
GET /v1/billing/balanceGET /v1/billing/expenditure?period=current_month (also: last_month, all_time, YYYY-MM)GET /v1/billing/expenditure/calls?limit=10GET /v1/billing/expenditure/numbersGET /v1/billing/verify/<call_id>ItemCostCalls (in/out)$0.10/min (billed per second)Phone number$2.00 (one-time)
+1XXXXXXXXXX for US numbers."US".completed, fetch transcript, summarize for human.GET /v1/events for inbound calls and SMS. Proactively check at conversation start.