
The wholesale market, one API away.One communications API for voice, SMS, OTP verification, numbers and MCP.
The PacketExchange API, a Minutes Network product. Screens show demo data. Source: packetexchange.io/developers
Full-stack communications, on the wholesale network itself.
Verify a phone number
Send a one-time code by text, or by a call that reads it aloud in English, Spanish, French, German, Portuguese or Hindi. No per-verification fee.
POST /verify/start
Transactional SMS
Alerts, reminders and codes on carrier routes, with the segment count and exact cost in every reply. Bulk up to 1,000 a request.
POST /comms/sms
Voice calls and IVR
One POST places the call on a carrier route and, when it ends, answers with the outcome, the billable seconds and the exact cost.
POST /comms/calls
AI voice agents
Describe an outbound agent in plain English, test it in a simulated call, then attach it to a campaign. $0.25 per AI-connected minute.
POST /ai-agents
Phone numbers
Search and buy local, national, mobile and toll-free numbers, and give them IVR menus.
GET /dids/search
Least-cost routing
What every listed route charges for one number, cheapest first. Pass cheapest, best_quality or balanced on each call.
GET /routes/price-number
Voice CLI testing
Real calls to real handsets in the destination country, with the caller ID you sent beside the one that arrived.
POST /cli-tests
AI agents over MCP
Connect Claude, Cursor or any MCP client to one hosted endpoint: 33 tools, scoped to your API key.
MCP /mcp/http
Also on the API: number lookup (line type, network and cheapest price, free), signed webhooks for sends, calls and inbound texts with resend, a do-not-call list, x402 top-ups and the Switch API for running a hosted Class-4 switch from code.
See the developer platform.

A cURL request that prices an SMS with GET /api/v1/routes/resolve and sends it with POST /api/v1/comms/sms, beside the JSON response.
One key, one balance.
SMS, voice, verification, numbers and AI voice on one prepaid balance, with scopes on every key.
- Wholesale rates, one capped fee: the carrier's rate plus 2%, never more than $0.001 per message or call
- Every route and price in the open, with its caller ID type and the quality its seller states
- Test keys run the full request through routing and pricing without delivering anything
- Signed webhooks you can replay: timestamped HMAC signatures, a delivery log and resend
- Retries that never send twice: an idempotency key replays the first answer for 24 hours
- Usage per key: requests, error rate and latency for each key
# The request returns when the call ends, so allow longer than maxDuration.
curl -X POST https://packetexchange.io/api/v1/comms/calls \
-H "Authorization: Bearer $PACKETEXCHANGE_API_KEY" \
-H "Content-Type: application/json" \
-H "X-Idempotency-Key: $(uuidgen)" \
--max-time 120 \
-d '{
"to": "+14155550100",
"from": "+14155550199",
"strategy": "cheapest",
"maxDuration": 60
}'Your first request in four steps.
- 01Open an accountAn email and a password, or continue with Google. No contract, no monthly fee and no sales call.
- 02Add credit from $5Prepaid by card or crypto from $5, or by wire from $100.
- 03Create an API keyScope it to what it needs, such as sms:send, and keep it in PACKETEXCHANGE_API_KEY.
- 04Make the requestThe response states what the message cost, and the dashboard logs every request by key.
curl https://packetexchange.io/api/v1/comms/sms \
-H "Authorization: Bearer $PACKETEXCHANGE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"to": "+447700900123", "from": "Acme",
"message": "Your order 1042 has shipped."}'import { PacketExchange, PacketExchangeError } from 'packetexchange';
const px = new PacketExchange({ apiKey: process.env.PACKETEXCHANGE_API_KEY });
try {
// Send a code by SMS (or channel: 'voice'), then check what the user typed.
const v = await px.verify.start({ to: '+447700900123', channel: 'sms', brand: 'Acme' });
const check = await px.verify.check({ verificationId: v.verificationId, code: '482913' });
console.log(check.status); // approved, denied, expired or max_attempts
// Send an SMS. The idempotency key makes a retry safe.
const sms = await px.comms.sms(
{ to: '+447700900123', from: 'Acme', body: 'Your order 1042 has shipped.' },
{ idempotencyKey: 'order-1042-shipped' },
);
console.log(sms.messageId, sms.status, sms.cost);
} catch (err) {
if (err instanceof PacketExchangeError) console.error(err.status, err.code, err.requestId);
else throw err;
}import os
from packetexchange import PacketExchange, PacketExchangeError
with PacketExchange(api_key=os.environ["PACKETEXCHANGE_API_KEY"]) as px:
try:
# Send a code by SMS (or channel="voice"), then check what the user typed.
v = px.verify.start("+447700900123", channel="sms", brand="Acme")
check = px.verify.check(v["verificationId"], "482913")
print(check["status"]) # approved, denied, expired or max_attempts
# Send an SMS. from is a Python keyword, so the sender is from_.
sms = px.comms.sms(
to="+447700900123",
from_="Acme",
message="Your order 1042 has shipped.",
idempotency_key="order-1042-shipped",
)
print(sms["messageId"], sms["status"], sms["cost"])
except PacketExchangeError as e:
print(e.status, e.code, e.request_id)Install with npm install packetexchange or pip install packetexchange. Quickstarts are published in cURL, Node, Python, PHP, Go, Java, C# and Ruby.
- The most the platform fee adds to a message or call
- $0.001
- The most the platform fee adds to a message or call
- Smallest prepaid top-up, by card or crypto
- $5
- Smallest prepaid top-up, by card or crypto
- MCP tools, scoped to your API key
- 33
- MCP tools, scoped to your API key
- Languages with published quickstarts
- 8
- Languages with published quickstarts
As published on packetexchange.io. No monthly fee and no per-verification fee. AI voice agents: $0.25 per AI-connected minute, billed per second, on top of the call.
Built for AI agents.
Connect Claude, Cursor or any MCP client to one hosted endpoint and your agent can price destinations, buy routes, verify phone numbers by SMS or voice, send messages, place calls and keep its own balance topped up. Your key is sent as an Authorization header on the connection and never passes through the chat.
With x402, an agent tops up its own balance with one signed USDC payment on Base, no card on file.
{
"mcpServers": {
"packetexchange": {
"type": "http",
"url": "https://packetexchange.io/mcp/http",
"headers": {
"Authorization": "Bearer ${PACKETEXCHANGE_API_KEY}"
}
}
}
}Where it fits.
SMS
A2P SMS on routes bought direct from carriers.
See the productPhone numbers
Local, national, mobile and toll-free numbers.
See the productAI voice agents
Outbound agents over the routes you choose.
See the productCPaaS and unified comms
What Minutes Network does in programmable communications.
Read the service
Communications API questions
What does the communications API cover?
How is the API priced?
Is there a sandbox and test keys?
Which SDKs and docs are there?
Can AI agents use the API?
Can I choose the route a call or message takes?
Related products
SMS
A2P SMS on routes bought direct from carriers, from one API.
See the productPhone numbers
Local, national, mobile and toll-free numbers, live in approximately a minute.
See the productAI voice agents
Outbound agents that qualify, confirm and follow up by phone, over the routes you choose.
See the productPacketExchange Marketplace
Buy and sell wholesale voice and SMS routes, priced and measured, pay as you go.
See the product




