MultiMessage

MultiMessage API

A simple REST API so third-party platforms and AI agents can send texts, read replies, check how many texts are left this month, and upgrade the plan on demand.

Full endpoint reference →

Machine-readable resources: OpenAPI 3.0 spec · llms.txt (agent guide) · GET /api/v1 discovery index (no auth).

Authentication

Create an API key in the app (it's shown once — store it safely), then send it as a Bearer token on every request:

Authorization: Bearer mm_live_XXXXXXXX

Keys are scoped to your account, stored only as a hash, and can be revoked at any time from the app. Rate limit: 120 requests/minute per key.

Check remaining texts

curl https://multimessage.me/api/v1/usage \
  -H "Authorization: Bearer $KEY"

{"plan": "growth", "can_send": true, "reason": "ok",
 "texts_used": 412, "texts_cap": 2500, "texts_remaining": 2088,
 "unlimited": false, "period": "calendar_month_utc",
 "resets_at": "2026-08-01T00:00:00Z"}

Send a text

curl -X POST https://multimessage.me/api/v1/messages \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"address": "+17065551212", "body": "Hi! Just following up.",
       "client_ref": "order-1042"}'

Sends are idempotent on client_ref — retrying with the same value never double-sends. Every send response includes your updated usage. When the monthly cap is reached the API answers 402 with code cap_reached and a hint to upgrade.

Track delivery & wait for replies

GET /api/v1/messages/1042           # one message's delivery status
GET /api/v1/messages?since=<cursor>&wait=25   # long-poll for anything new

Poll with the returned cursor; wait holds the request open (up to 25s) until a reply or status update arrives — no tight polling.

Upgrade your plan on demand

curl -X POST https://multimessage.me/api/v1/plan \
  -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -d '{"plan": "pro"}'

With an active subscription the price is switched in place (prorated) and the new cap applies immediately. Without one, the response contains a checkout_url to complete payment. Available tiers: GET /api/v1/tiers.

Read conversations

GET /api/v1/threads                       # conversation list
GET /api/v1/threads/+17065551212/messages # one conversation (any number format works)

Errors

Every error is JSON with a human reason and a stable machine-readable code:

{"error": "monthly text cap reached — upgrade via POST /api/v1/plan",
 "code": "cap_reached"}

Codes: invalid_api_key (401) · rate_limited (429) · invalid_request, invalid_address, unknown_plan (400) · no_subscription, cap_reached, no_plan (402) · no_route, exempt_account (409) · not_found (404) · billing_disabled (503) · stripe_error (502).

Need higher volume or a custom integration? [email protected]