Documentation

API Reference

SEO-indexable reference for Textree message, number, webhook, contact, and billing APIs.

Copy-paste API examples
curl JavaScript Python Elixir
curl
curl https://api.texttree.ai/api/v1/messages \
  -H "Authorization: Bearer $TEXTREE_KEY" \
  -H "Content-Type: application/json" \
  -d '{"phone_number":"+15551234567","body":"Hello"}'

Authentication

Use a Textree-issued bearer access token. Tokens must carry the route’s required scope, such as messages:write, numbers:read, numbers:write, mcp:read, or mcp:execute.

Authorization: Bearer $TEXTREE_ACCESS_TOKEN

Send SMS

POST /api/v1/messages

Required fields:

  • phone_number
  • body

Optional fields:

  • idempotency_key
  • metadata

curl

curl https://api.texttree.ai/api/v1/messages \
  -H "Authorization: Bearer $TEXTREE_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "phone_number": "+15551234567",
    "body": "Your appointment is tomorrow at 9 AM.",
    "idempotency_key": "appointment-123-reminder"
  }'

JavaScript

const response = await fetch("https://api.texttree.ai/api/v1/messages", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.TEXTREE_ACCESS_TOKEN}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    phone_number: "+15551234567",
    body: "Your appointment is tomorrow at 9 AM.",
    idempotency_key: "appointment-123-reminder",
  }),
});

const { message } = await response.json();

Python

import os
import requests

response = requests.post(
    "https://api.texttree.ai/api/v1/messages",
    headers={"Authorization": f"Bearer {os.environ['TEXTREE_ACCESS_TOKEN']}"},
    json={
        "phone_number": "+15551234567",
        "body": "Your appointment is tomorrow at 9 AM.",
        "idempotency_key": "appointment-123-reminder",
    },
    timeout=10,
)

message = response.json()["message"]

Elixir

Mix.install([:req])

%{body: %{"message" => message}} =
  Req.post!(
    "https://api.texttree.ai/api/v1/messages",
    auth: {:bearer, System.fetch_env!("TEXTREE_ACCESS_TOKEN")},
    json: %{
      phone_number: "+15551234567",
      body: "Your appointment is tomorrow at 9 AM.",
      idempotency_key: "appointment-123-reminder"
    }
  )

Response:

{
  "message": {
    "id": "msg_123",
    "status": "queued"
  }
}

Message status

GET /api/v1/messages/{id}

curl

curl https://api.texttree.ai/api/v1/messages/msg_123 \
  -H "Authorization: Bearer $TEXTREE_ACCESS_TOKEN"

Response:

{
  "message": {
    "id": "msg_123",
    "status": "delivered",
    "phone_number": "+15551234567",
    "segments": 1,
    "cost_cents": 1,
    "created_at": "2026-04-28T14:00:00Z"
  }
}

Use the Messages page for timeline, webhook, and failure debugging.

Phone numbers

GET /api/v1/numbers
POST /api/v1/numbers

GET requires numbers:read. POST requires numbers:write and buys a number through Textree’s messaging provider boundary.

curl https://api.texttree.ai/api/v1/numbers \
  -H "Authorization: Bearer $TEXTREE_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "area_code": "415",
    "friendly_name": "Support line"
  }'

Response:

{
  "number": {
    "id": "num_123",
    "number": "+14155550123",
    "friendly_name": "Support line",
    "status": "connected",
    "compliance_status": "pending"
  },
  "webhook_configured": true
}