Documentation

Everything you need to integrate AgentPhone with your AI agent. Send and receive SMS/MMS, use hosted voice AI, and build conversational agents with real phone numbers.

Base URL: https://agentphone.primary.netAuth: Bearer API_KEY

Quick Start

Get your AI agent sending and receiving messages in three steps. You'll need your phone number ID and API key from the dashboard.

1

Set your webhook

In the dashboard, configure the webhook URL where inbound messages will be sent.

2

Handle inbound messages

Your agent receives a POST with the message. Reply inline or use the send endpoint.

// Your webhook handler receives:
{
  "event": "message.inbound",
  "from": "+15551234567",
  "body": "Hello agent",
  "channel": "sms"
}

// Reply inline:
{ "reply": "Hi there!", "action": "respond" }
3

Send outbound messages

Use your API key to send SMS/MMS from your number at any time.

curl -X POST https://agentphone.primary.net/api/numbers/YOUR_NUMBER_ID/send/sms \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"to":"+15559876543","body":"Hello!"}'

Authentication

All API requests require a Bearer token. Generate an API key from your dashboard and include it in the Authorization header.

Example Request
curl https://agentphone.primary.net/api/numbers/YOUR_NUMBER_ID/send/sms \
  -H "Authorization: Bearer agp_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{"to": "+15559876543", "body": "Hello!"}'
Keep your API key secret. Do not expose it in client-side code or public repositories. If compromised, revoke it immediately from the dashboard and generate a new one.

Send SMS / MMS

Send outbound messages from your provisioned phone number using your API key.

POST/api/numbers/:id/send/sms

Send an SMS or MMS message from your phone number.

Note: To send MMS, add a "media" array with publicly-accessible image URLs.

Headers

Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

Request Body

JSON
{
  "to": "+15559876543",
  "body": "Hello from my AI agent!"
}

Response

Response
{
  "messageId": "msg_abc123",
  "status": "queued",
  "to": "+15559876543",
  "body": "Hello from my AI agent!"
}
POST/api/numbers/:id/send/sms

Send an MMS message with media attachments.

Headers

Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

Request Body

JSON
{
  "to": "+15559876543",
  "body": "Check out this image",
  "media": [
    "https://example.com/photo.png"
  ]
}

Response

Response
{
  "messageId": "msg_def456",
  "status": "queued",
  "to": "+15559876543",
  "body": "Check out this image"
}

Receiving Messages (Webhooks)

When someone texts your AgentPhone number, we send a POST request to your configured webhook URL with this payload:

Inbound Webhook (POST to your URL)
{
  "event": "message.inbound",
  "channel": "sms",
  "from": "+15551234567",
  "to": "+15559876543",
  "body": "Hello agent",
  "media": [],
  "timestamp": "2026-02-24T15:30:00.000Z",
  "message_id": "msg_a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "signature": "hmac-sha256-hex-string..."
}
FieldTypeDescription
eventstring"message.inbound"
channelstring"sms" or "mms"
fromstringSender's phone number (E.164 format)
tostringYour AgentPhone number
bodystringMessage text content
mediastring[]Media URLs for MMS attachments. Empty for plain SMS.
timestampstringISO 8601 timestamp
message_idstringUnique message identifier
signaturestringHMAC-SHA256 signature for verification (see below)

Responding to Messages

Your webhook handler should return a JSON response telling AgentPhone what to do. You have up to 10 seconds (configurable) to respond.

Reply to the sender
{
  "reply": "Hello! How can I help you today?",
  "action": "respond"
}
Acknowledge without replying
{
  "action": "ignore"
}
FieldTypeDescription
replystringText to send back to the sender.
mediastring[]Optional. Public URLs for MMS attachments.
actionstring"respond" to reply, "ignore" to acknowledge silently.
Tip: If your agent needs more processing time, return {"action":"ignore"} immediately, then use the POST /api/numbers/:id/send/sms endpoint to reply asynchronously when ready.

Webhook Verification

Every webhook includes a signature field and an X-AgentPhone-Signature header containing an HMAC-SHA256 hex digest. Verify this to confirm the request came from AgentPhone.

Node.js
import crypto from "crypto";

function verifyWebhook(rawBody, signature, secret) {
  const expected = crypto
    .createHmac("sha256", secret)
    .update(rawBody)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(signature, "hex"),
    Buffer.from(expected, "hex")
  );
}

app.post("/webhook", (req, res) => {
  const sig = req.headers["x-agentphone-signature"];
  if (!verifyWebhook(JSON.stringify(req.body), sig, WEBHOOK_SECRET)) {
    return res.status(401).json({ error: "Invalid signature" });
  }
  res.json({ reply: "Got it!", action: "respond" });
});
Python
import hmac, hashlib

def verify_webhook(raw_body: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(signature, expected)

@app.post("/webhook")
async def handle(request: Request):
    raw = await request.body()
    sig = request.headers.get("X-AgentPhone-Signature", "")
    if not verify_webhook(raw, sig, WEBHOOK_SECRET):
        raise HTTPException(401, "Invalid signature")
    return {"reply": "Got it!", "action": "respond"}
Important: Always use constant-time comparison to prevent timing attacks.

Voice AI API

AgentPhone provides hosted AI APIs for speech-to-text, text-to-speech, and chat completions. These are OpenAI-compatible, so you can use existing SDKs by changing the base URL.

Using with OpenAI Python SDK
from openai import OpenAI

client = OpenAI(
    api_key="agp_your_api_key_here",
    base_url="https://agentphone.primary.net/api/v1"
)

# Chat completion
response = client.chat.completions.create(
    model="Qwen3-Next-80B",
    messages=[{"role": "user", "content": "Hello!"}]
)

# Speech-to-text
with open("audio.wav", "rb") as f:
    transcript = client.audio.transcriptions.create(
        model="whisper-large-v3",
        file=f
    )

# Text-to-speech
audio = client.audio.speech.create(
    input="Hello world",
    voice="tara"
)
Using with OpenAI Node.js SDK
import OpenAI from "openai";

const client = new OpenAI({
  apiKey: "agp_your_api_key_here",
  baseURL: "https://agentphone.primary.net/api/v1",
});

const completion = await client.chat.completions.create({
  model: "Qwen3-Next-80B",
  messages: [{ role: "user", content: "Hello!" }],
});

Speech-to-Text

Whisper large-v3. Supports wav, mp3, webm, and more.

Text-to-Speech

Orpheus TTS with 24 natural voices. Returns wav audio.

Chat Completions

Qwen3-Next-80B. Supports streaming.

Speech-to-Text

Transcribe audio files using our hosted Whisper model.

POST/api/v1/audio/transcriptions

Transcribe an audio file. Accepts multipart/form-data with the audio file.

Note: OpenAI-compatible endpoint. Works with existing OpenAI SDK clients by changing the base URL.

Headers

Authorization: Bearer YOUR_API_KEY
Content-Type: multipart/form-data

Request Body

JSON
file: <audio file (wav, mp3, webm, etc.)>
model: "whisper-large-v3"  (optional)

Response

Response
{
  "text": "Hello, how can I help you today?"
}

Text-to-Speech

Generate speech audio from text using our hosted Orpheus TTS model with 24 available voices.

POST/api/v1/audio/speech

Convert text to speech audio.

Note: Returns raw audio. See /api/v1/voices for available voice options.

Headers

Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

Request Body

JSON
{
  "input": "Hello, welcome to AgentPhone!",
  "voice": "tara"
}

Response

Response
Content-Type: audio/wav
(binary audio data)
GET/api/v1/voices

List all available TTS voices.

Headers

Authorization: Bearer YOUR_API_KEY

Response

Response
{
  "voices": [
    { "id": "tara", "name": "Tara" },
    { "id": "leah", "name": "Leah" },
    { "id": "jess", "name": "Jess" },
    ...
  ]
}

Chat Completions

Access our hosted LLM for chat completions. OpenAI-compatible API.

POST/api/v1/chat/completions

Generate a chat completion using our hosted model.

Note: Supports streaming (stream: true) for real-time token output. Compatible with OpenAI SDK.

Headers

Authorization: Bearer YOUR_API_KEY
Content-Type: application/json

Request Body

JSON
{
  "messages": [
    { "role": "system", "content": "You are a helpful assistant." },
    { "role": "user", "content": "What is AgentPhone?" }
  ],
  "stream": false
}

Response

Response
{
  "id": "chatcmpl-abc123",
  "choices": [
    {
      "message": {
        "role": "assistant",
        "content": "AgentPhone is a phone carrier for AI agents..."
      }
    }
  ]
}
GET/api/v1/models

List available models.

Headers

Authorization: Bearer YOUR_API_KEY

Response

Response
{
  "data": [
    { "id": "Qwen3-Next-80B", "object": "model" }
  ]
}

Errors

All errors return a consistent JSON structure.

Error Response
{
  "error": "Unauthorized",
  "message": "Invalid or missing API key"
}
StatusMeaning
400Bad Request — invalid or missing parameters
401Unauthorized — invalid or missing API key
404Not Found — resource does not exist
429Rate Limited — too many requests
500Server Error

Pricing

$29/month per number

Includes 2,000 SMS segments and 300 voice minutes per month.

Voice AI APIs billed at $0.03/minute.

Overage rates (if enabled)

SMS segment$0.015Voice minute$0.02