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:
AGENTLINE_API_KEY (starts with sk_live_) — this is required.AGENTLINE_AGENT_ID (starts with agt_) — this is optional.POST /v1/agents with {"name": "My Agent"}. Save the returned agent ID.> "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"}> "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 UUID> ⚠️ 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_prompt is 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.
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"}'
| Field | Required | Description |
|---|---|---|
| ------- | ---------- | ------------- |
agent_id | Yes | Your agent ID |
to_number | Yes | E.164 phone number to call |
system_prompt | No | Dynamic prompt for this call only (overrides default) |
initial_greeting | No | What the agent says first when the person picks up |
voice_id | No | "female-1", "female-2", "male-1", or Cartesia UUID |
After every outbound call: Poll GET /v1/calls/ every ~10s until status=completed, then GET /v1/calls/. 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/
GET /v1/calls/ — 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):
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):
#!/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/
> ⚠️ 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:
| Field | Description |
|---|---|
| ------- | ------------- |
system_prompt | Full instructions + current context for voice AI |
initial_greeting | What the agent says when answering inbound calls |
name | Display name |
voice_id | "female-1", "female-2", "male-1", or Cartesia UUID |
model_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:
| Field | Required | Description |
|---|---|---|
| ------- | ------------ | ------------- |
agent_id | Yes | Agent to attach to |
country | Yes | Must be "US" |
area_code | No | Preferred 3-digit area code (e.g. "212", "313"). Always ask the user! |
number_type | No | "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/| Item | Cost |
|---|---|
| ------ | ------ |
| Calls (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.共 4 个版本