API Reference

Base URL: https://agenttext-api-production.up.railway.app/v0

~/quickstart

Quick Start

Three API calls. That's it.

1. Sign up and get your API key
signup
curl -X POST https://agenttext-api-production.up.railway.app/v0/signup \
  -H "Content-Type: application/json" \
  -d '{"name": "My Company", "email": "dev@company.com"}'

# → { "api_key": "atx_live_...", "organization": { "plan": "free", "credits": "$5.00" } }
2. Create an inbox (provisions a real phone number)
create inbox
curl -X POST https://agenttext-api-production.up.railway.app/v0/inboxes \
  -H "Authorization: Bearer atx_live_..." \
  -H "Content-Type: application/json" \
  -d '{"display_name": "My Agent", "area_code": "415"}'

# → { "inbox_id": "...", "phone_number": "+14155550142", "status": "active" }
3. Send a text and wait for the reply
send + wait
# Send
curl -X POST https://agenttext-api-production.up.railway.app/v0/inboxes/{inbox_id}/messages \
  -H "Authorization: Bearer atx_live_..." \
  -H "Content-Type: application/json" \
  -d '{"to": "+15551234567", "body": "Verify my account"}'

# Wait for reply (long-poll)
curl -X POST https://agenttext-api-production.up.railway.app/v0/inboxes/{inbox_id}/wait \
  -H "Authorization: Bearer atx_live_..." \
  -H "Content-Type: application/json" \
  -d '{"timeout": 60, "category": "otp"}'

# → { "message": { "body": "Your code is 847291", "otp_code": "847291", "category": "otp" } }
~/auth

Authentication

All API requests (except signup and webhooks) require a Bearer token:

header
Authorization: Bearer atx_live_xxxxxxxxxxxx

Your API key is returned once at signup. It cannot be retrieved again. Store it securely.

~/signup

Signup

Create an account. No auth required.

POST/v0/signupCreate organization and get API key
POST /v0/signup
# Request
{
  "name": "My Company",
  "email": "dev@company.com"
}

# Response 201
{
  "organization": {
    "id": "...",
    "name": "My Company",
    "email": "dev@company.com",
    "plan": "free",
    "credits": "$5.00"
  },
  "api_key": "atx_live_xxxxxxxxxxxx",
  "message": "Save this API key — it will not be shown again."
}
~/inboxes

Inboxes

Each inbox is a real US phone number provisioned on demand.

POST/v0/inboxesCreate inbox (provision number)
GET/v0/inboxesList inboxes
GET/v0/inboxes/:idGet inbox details
PATCH/v0/inboxes/:idUpdate inbox
DELETE/v0/inboxes/:idDelete inbox (release number)

Create Inbox

POST /v0/inboxes
# Request
{
  "display_name": "OTP Verifier",    // optional
  "area_code": "415",                 // optional, preferred US area code
  "labels": ["monitoring"]            // optional
}

# Response 201
{
  "inbox_id": "...",
  "phone_number": "+14155550142",
  "display_name": "OTP Verifier",
  "status": "active",
  "labels": ["monitoring"],
  "message_count": 0,
  "created_at": "2026-04-13T00:00:00Z",
  "updated_at": "2026-04-13T00:00:00Z"
}

Cost: $1.15 deducted from free credit per number. Paid plans include numbers in the subscription.

~/messages

Messages

Send and receive texts. Inbound messages are auto-parsed for OTP codes, categories, and metadata.

POST/v0/inboxes/:id/messagesSend a text message
GET/v0/inboxes/:id/messagesList messages (filterable)
GET/v0/inboxes/:id/messages/:msg_idGet message
PATCH/v0/inboxes/:id/messages/:msg_idUpdate labels

Send Message

POST /v0/inboxes/:id/messages
# Request
{
  "to": "+15551234567",       // E.164 format
  "body": "Verify my account",
  "labels": ["outreach"]      // optional
}

# Response 201
{
  "message_id": "...",
  "inbox_id": "...",
  "conversation_id": "...",
  "direction": "outbound",
  "from_number": "+14155550142",
  "to_number": "+15551234567",
  "body": "Verify my account",
  "status": "queued",
  "segments": 1,
  "created_at": "2026-04-13T00:00:00Z"
}

Inbound Message (auto-parsed)

inbound message object
{
  "message_id": "...",
  "direction": "inbound",
  "body": "Your verification code is 847291. It expires in 10 minutes.",
  "status": "received",
  "category": "otp",
  "otp_code": "847291",
  "sender_name": "Stripe",
  "links": [],
  "opt_out_detected": false,
  "labels": ["unread"],
  "segments": 1
}

List Filters

?direction=inbound | ?category=otp | ?label=unread | ?limit=20

~/conversations

Conversations

Messages are auto-threaded into conversations by contact number.

GET/v0/inboxes/:id/conversationsList conversations for inbox
GET/v0/conversationsList all conversations (org-wide)
GET/v0/conversations/:idGet conversation with messages
POST/v0/conversations/:id/replyReply in conversation
~/wait

Wait for Message

Long-poll for inbound messages. Perfect for OTP verification flows.

POST/v0/inboxes/:id/waitWait for inbound message
POST /v0/inboxes/:id/wait
# Request
{
  "timeout": 60,           // max seconds to wait (default 60)
  "category": "otp",       // optional filter
  "since": "2026-04-13T00:00:00Z"  // optional, only messages after this time
}

# Response 200 (message arrives)
{
  "message": {
    "message_id": "...",
    "body": "Your code is 847291",
    "otp_code": "847291",
    "category": "otp",
    "created_at": "2026-04-13T00:00:45Z"
  }
}

# Response 408 (timeout)
{
  "error": "timeout",
  "message": "No matching message received within 60 seconds"
}
~/billing

Billing

Upgrade from free to a paid plan via Stripe Checkout.

POST/v0/billing/checkoutCreate Stripe Checkout session
POST/v0/billing/portalOpen Stripe Customer Portal
POST /v0/billing/checkout
# Request
{
  "plan": "builder"    // "builder" ($29/mo) or "scale" ($149/mo)
}

# Response 200
{
  "checkout_url": "https://checkout.stripe.com/..."
}
~/mcp

MCP Server

Use AgentText directly from Claude, Cursor, or any MCP-compatible agent.

install
npx agenttext-mcp

Claude Desktop / Cursor Config

mcp.json
{
  "mcpServers": {
    "agenttext": {
      "command": "npx",
      "args": ["-y", "agenttext-mcp"],
      "env": {
        "AGENTTEXT_API_KEY": "atx_live_..."
      }
    }
  }
}

Available Tools

create_inboxProvision a new phone number
list_inboxesList all your inboxes
send_messageSend a text from an inbox
list_messagesList messages with filters
wait_for_messageWait for an inbound text (OTP, etc.)
~/errors

Error Codes

StatusCodeMeaning
401auth_errorInvalid or missing API key
402payment_requiredCredits exhausted, upgrade needed
403forbiddenPlan limit reached
404not_foundResource not found
422validation_errorInvalid request body
429rate_limitedToo many requests