TextPilot

API Reference

REST API endpoints for TextPilot

API Reference

Base URL: https://textpilot-api.jackrgisel.workers.dev

All /v1 endpoints require a Bearer API key in the Authorization header.

Authorization: Bearer tp_live_...

POST /v1/messages

Send an SMS message.

Request

curl -X POST https://textpilot-api.jackrgisel.workers.dev/v1/messages \
  -H "Authorization: Bearer tp_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+16195551234",
    "message": "Your verification code is 4821",
    "tag": "otp"
  }'

Request Body

FieldTypeRequiredDescription
tostringYesPhone number in E.164 format
messagestringYesMessage body (1–1600 characters)
tagstringNoOptional tag for filtering

Response 201

{
  "id": "msg_a1b2c3d4e5f6",
  "status": "queued",
  "to": "+16195551234",
  "createdAt": "2026-03-09T12:00:00.000Z"
}

Errors

StatusBodyCause
400{ "error": "..." }Invalid phone number or empty message
401{ "error": "..." }Missing or invalid API key
402{ "error": "..." }Insufficient credits

GET /v1/messages

List messages for the authenticated project.

Request

curl https://textpilot-api.jackrgisel.workers.dev/v1/messages \
  -H "Authorization: Bearer tp_live_..."

Query Parameters

ParamTypeDefaultDescription
limitnumber50Max messages to return
cursorstringPagination cursor

Response 200

{
  "data": [
    {
      "id": "msg_...",
      "to": "+16195551234",
      "body": "Your code is 4821",
      "status": "sent",
      "tag": "otp",
      "snsMessageId": "sns-...",
      "createdAt": 1709913600000,
      "updatedAt": 1709913601000
    }
  ],
  "cursor": null
}

GET /v1/messages/:id

Get a single message by ID.

Request

curl https://textpilot-api.jackrgisel.workers.dev/v1/messages/msg_a1b2c3d4 \
  -H "Authorization: Bearer tp_live_..."

Response 200

Returns a single message object (same shape as items in the list response).

POST /v1/webhooks

Set a webhook URL for delivery status callbacks.

Request

curl -X POST https://textpilot-api.jackrgisel.workers.dev/v1/webhooks \
  -H "Authorization: Bearer tp_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "url": "https://myapp.com/webhooks/sms" }'

Response 200

{
  "id": "wh_...",
  "url": "https://myapp.com/webhooks/sms",
  "createdAt": "2026-03-09T12:00:00.000Z"
}

DELETE /v1/webhooks

Remove the project's webhook.

Request

curl -X DELETE https://textpilot-api.jackrgisel.workers.dev/v1/webhooks \
  -H "Authorization: Bearer tp_live_..."

Response 200

{ "success": true }

Authentication

API keys are project-scoped. Each key authenticates requests for a single project. Keys use the format tp_live_ followed by 32 hex characters.

Keys are hashed with SHA-256 before storage — the raw key is only shown once at creation time. Store it securely.

Rate Limits

No hard rate limits are enforced in Phase 1. Messages are queued via Cloudflare Queues and processed asynchronously. Abuse protection will be added in a future release.

Message Statuses

StatusDescription
queuedMessage accepted, waiting in queue
sentMessage delivered to carrier via AWS End User Messaging
deliveredCarrier confirmed delivery (future)
failedSend failed after retries

International SMS

Messages can be sent to 30+ countries. Cost varies by destination (1–8¢ per message). See the international SMS guide for the full rate table.

Inbound SMS Webhooks

When a message is received on a provisioned phone number, TextPilot sends a POST to your webhook URL with an X-TextPilot-Signature header. See the inbound SMS guide for details.