Skip to content

Quickstart, Voice

Build an AI voice agent

Describe what the agent says and the rules it keeps. Rehearse it turn by turn with no call placed, then attach it to a dialer campaign that calls over the routes you choose.
Calls
POST/ai-agentsPOST/ai-agents/{id}/simulatePUT/dialer/campaigns/{id}
Scope
dialer:write
Cost
Creating and simulating an agent is free. On live calls, one flat rate per AI-connected minute ($0.25 by default, billed per second) is added to the route cost.
On this page
  1. Step 1Get an API key
  2. Step 2Fund the balance
  3. Step 3Make the request
  4. Step 4Handle the response
  5. Step 5Go further

Step 1

Get an API key

Open an account, then create a key under Dashboard, API keys. Live keys (wmmn_live_sk_) send real traffic and charge your balance. Test keys (wmmn_test_sk_) run the same request through routing and pricing without delivering it, and draw on test credit, which comes with an invite code.

A key restricted to scopes needs dialer:write. GET /ai-agents/voices lists the voices the agent can speak with.

Every sample reads the key from the environment. Keep it out of source control.

export PACKETEXCHANGE_API_KEY=wmmn_live_sk_...

Step 2

Fund the balance

PacketExchange is prepaid. Top up from $5 by card or crypto, or from $100 by wire, under Dashboard, Billing. An agent can top itself up with x402. There is no contract and no monthly fee.

Nothing is billed until the agent is on a live campaign call. Then the route is billed as a normal call, plus the AI-connected minutes.

Cost

Creating and simulating an agent is free. On live calls, one flat rate per AI-connected minute ($0.25 by default, billed per second) is added to the route cost.

Step 3

Make the request

Create the agent with a name, the first thing it says and its instructions (systemPrompt), then send one line as the person on the call and read the agent's reply.

# 1. Create the agent: what it says first, and the instructions it follows.
agent_id=$(curl -s https://packetexchange.io/api/v1/ai-agents \
  -H "Authorization: Bearer $PACKETEXCHANGE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Appointment confirmation",
    "language": "en",
    "firstMessage": "Hello, this is Riverside Clinic calling to confirm your appointment tomorrow at 10:30.",
    "systemPrompt": "You confirm appointments for Riverside Clinic. Ask whether the person can attend tomorrow at 10:30. Keep every reply short and polite.",
    "maxCallSeconds": 180
  }' | jq -r .data.id)

# 2. Rehearse one turn. No call is placed and nothing is billed.
curl -s "https://packetexchange.io/api/v1/ai-agents/$agent_id/simulate" \
  -H "Authorization: Bearer $PACKETEXCHANGE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"message": "Yes, I can still make it."}' | jq .data
Save as request.sh, run bash request.shNeeds curl, plus jq for the multi-step samples

Step 4

Handle the response

Creating returns the agent. Each simulated turn returns what the agent would say and what it would do next.

201 CreatedPOST /ai-agents
{
  "success": true,
  "data": {
    "id": "<uuid>",
    "name": "Appointment confirmation",
    "language": "en",
    "firstMessage": "Hello, this is Riverside Clinic calling to confirm...",
    "systemPrompt": "You confirm appointments for Riverside Clinic...",
    "maxCallSeconds": 180,
    "enabled": <boolean>,
    "createdAt": "<ISO-8601 UTC>"
  }
}
200 OKPOST /ai-agents/{id}/simulate
{
  "success": true,
  "data": {
    "reply": "<what the agent would say>",
    "action": "continue",
    "captured": {}
  }
}

Values in angle brackets are placeholders for your own ids, times and amounts.

Response fields

action
continue, end or transfer: what the agent would do after this turn.
captured
Structured details picked up this turn, such as a name or an intent.
history (request)
Pass earlier turns to simulate a whole conversation, up to 60 of them.
guardrails (request)
Hard rules the agent must never break, kept separate from the script.

When something goes wrong

  • Simulation is rate limited to 20 requests per minute.
  • To go live, PUT /dialer/campaigns/{id} with { "aiAgentId": "<agent id>" } on a campaign that is a draft, ready or paused.
  • Errors use the standard envelope with a VALIDATION_ERROR per bad field.
400The error envelope
{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid input",
    "details": [
      { "path": "to", "message": "<why the field was refused>" }
    ]
  }
}

Step 5

Go further

Run it with your own key

Open an account, add credit from $5 and create a key. You pay the carrier's rate plus a fee capped at $0.001.