iBlueText API

Base URL https://ibluetext.com/api/v1 · JSON over HTTPS.

Introduction

The iBlueText API lets you validate which numbers are on iMessage and send real blue-bubble messages from your dedicated line — straight from your own app, backend, or CRM. Every request is authenticated with an API key and returns JSON.

Which API for what

All endpoints share the same base URL and Bearer-key auth — they're grouped here by purpose so you pick the right one. Full details for each are in the sections below.

PurposeEndpoint
iPhone Lookup — is a number on iMessage?POST/GET /api/v1/lookup
Send — send an iMessage/SMSPOST/GET /api/v1/send
SMS Verify / 2FA — send & check a codePOST /api/v1/verify · /siteverify · /sites
Conversations — read full in/out message history (for CRMs / agents)GET /api/v1/conversations
Verified contacts — export widget-verified numbersGET /api/v1/contacts
Balance & usage — credits + per-line daily capsGET /api/v1/balance

Get a key under Integrations → API keys. Every request uses Authorization: Bearer <key> and only ever sees your own account's data.

For AI agents 🤖

iBlueText is built to be set up by an AI agent. A human verifies once (the only human step), then your agent does the rest via the API. There's a machine-readable summary at ibluetext.com/llms.txt.

Paste this to your agent (Claude or any) to get started:

I'm setting up iBlueText (https://ibluetext.com) for SMS/iMessage.
Read https://ibluetext.com/llms.txt and https://ibluetext.com/docs/.
I'll verify I'm human via SMS and give you my API key
(send it as: Authorization: Bearer <key>). Then:
  1) create a verify-widget site (POST /api/v1/sites) and give me the embed snippet,
  2) help me run an iPhone lookup (POST /api/v1/lookup) on my list,
  3) set up sending (POST /api/v1/send) as I describe.

Your agent can create widget sites, run lookups, send messages, and pull contacts entirely through the API — see the endpoints below.

Authentication

Create a key under Settings → API keys, then send it as a Bearer token on every request. Keep keys secret — anyone with a key can spend your credits.

Authorization: Bearer ibt_live_xxxxxxxxxxxxxxxxxxxxxxxx

Quickstart

Check whether three numbers are on iMessage:

curl https://ibluetext.com/api/v1/lookup \
  -H "Authorization: Bearer $IBT_KEY" \
  -H "Content-Type: application/json" \
  -d '{"numbers": ["+18135550142", "+17275550199", "+13055550123"]}'
{ "id": 8412, "status": "queued", "total": 3,
  "poll_url": "https://ibluetext.com/api/v1/lookup?id=8412" }

Then poll the poll_url until status is done.

POST/lookup

Submit numbers to validate. Numbers are de-duplicated and must include a country code. One lookup credit is spent per number (your first 100 are free).

Body

{ "numbers": ["+18135550142", "+17275550199"] }   // array, or comma-separated string

Response 201

{ "id": 8412, "status": "queued", "total": 2, "poll_url": "…/lookup?id=8412" }

GET/lookup?id=<id>

Fetch job progress and results. imessage is true (blue bubble), false (SMS), or null (not yet checked).

{ "id": 8412, "status": "done", "total": 2, "completed": 2, "iphones": 1,
  "results": [
    { "number": "+18135550142", "imessage": true,  "checked": true },
    { "number": "+17275550199", "imessage": false, "checked": true }
  ] }

POST/send

Queue an iMessage from your active sending line. Requires a provisioned line. Recipients who replied STOP are blocked automatically.

Body

{ "to": "+18135550142",
  "body": "Hi {firstname}! Your order shipped 🎉",
  "first_name": "Sarah",       // optional — fills {firstname}
  "line_id": 12 }               // optional — defaults to your first active line

Response 201

{ "id": 99213, "to": "+18135550142", "status": "queued", "poll_url": "…/send?id=99213" }

GET/send?id=<id>

{ "id": 99213, "to": "+18135550142", "channel": "imessage", "status": "delivered", "sent_at": "2026-06-17 14:02:11" }

Status values: queuedsentdelivered, or failed.

SMS Verify — widget & API

Add "verify you're human via SMS" to any form. Two ways:

Drop-in widget (easiest)

Create a site under SMS Verify to get a site_key, then paste this above your form's submit button:

<div class="ibt-verify" data-sitekey="ibt_site_xxx" data-theme="auto"></div>
<script src="https://ibluetext.com/v.js" async></script>

The widget gates your submit button until verified, then injects a hidden ibt_token field. Themes: auto / light / dark. It also emits an ibt-verified DOM event.

Where to place it: any form that collects a phone (signup, contact, checkout); the "add your phone" step after a Google/Apple login (social login gives you an email but no verified phone); or as a gatekeeper — render it on a page and only grant access (or call your backend) once the ibt-verified event fires or /siteverify confirms the token.

Capturing name & email: the widget auto-reads the name + email from the surrounding form and attaches them to the verified contact (so a contact form becomes name+email+verified-phone). Add data-require="name,email" to require those fields before the user can verify, or data-name-field/data-email-field (CSS selectors) to target specific inputs. Omit for phone-only capture.

Exactly where in the page:

For one-tap autofill (recommended): add autocomplete tokens to your own fields — name field autocomplete="name", email field type="email" autocomplete="email". The widget's phone input already has autocomplete="tel". With all three, iOS "AutoFill Contact" fills name + email + phone in one tap, and the verification code one-tap-fills on iPhone / auto-fills zero-tap on Android Chrome. The code field needs nothing extra — the widget handles it.

REST API (server-side)

# 1. start — send a code (server uses your secret API key)
curl https://ibluetext.com/api/v1/verify \
  -H "Authorization: Bearer $IBT_KEY" -H "Content-Type: application/json" \
  -d '{"phone":"+18135550142","page_url":"https://you.com/signup"}'
# -> { "id": 5512, "status": "queued" }

# 2. check — confirm the code the user typed
curl "https://ibluetext.com/api/v1/verify?action=check" \
  -H "Authorization: Bearer $IBT_KEY" -H "Content-Type: application/json" \
  -d '{"id":5512,"code":"481920"}'
# -> { "verified": true, "token": "…", "phone": "+18135550142", "channel": "imessage" }

The code is delivered by iMessage (iPhone) or SMS (Android) automatically. Each verification logs a proof-of-consent record (number, time, IP, page, consent text).

POST/siteverify

Confirm a widget token on your backend with your secret key (like Cloudflare's siteverify). Tokens are single-use.

curl https://ibluetext.com/api/v1/siteverify \
  -H "Content-Type: application/json" \
  -d '{"secret":"ibt_secret_xxx","token":""}'
# -> { "success": true, "phone": "+18135550142", "channel": "imessage", "verified_at": "…" }

GET/contacts

Pull your verified contacts — phone, name, email, channel, and verified time — to sync into your own database or CRM. Paginate with next_since.

curl "https://ibluetext.com/api/v1/contacts?since=0&limit=200" \
  -H "Authorization: Bearer $IBT_KEY"
# -> { "contacts":[ { "id":91, "phone":"+18135550142", "name":"Sarah Lee",
#        "email":"sarah@x.com", "channel":"imessage", "verified_at":"…" } ],
#      "count":1, "next_since":91 }

You can also download everything as CSV from SMS Verify → Download contacts.

Billing & the 402 "out of credits" error

The first 100 credits are free for testing. 1 credit = $0.005, spent by either one iPhone lookup or one SMS verification (shared pool). Separately, your first 10 SMS verifications are free (no card) — a distinct trial bucket from the 100 lookup credits. Sending iMessage/SMS instead needs an active line subscription ($99/mo + $249 setup), not credits.

When you run out, the paid endpoints return HTTP 402 with a machine-readable body so an AI agent knows exactly what to do:

{ "error": "payment_required",
  "reason": "insufficient_credits",      // or "subscription_required"
  "message": "…buy credits to continue.",
  "action": "lookup",                     // or "verify" / "send"
  "needed": 250, "available": 0, "unit_price_usd": 0.005,
  "human_action_required": true,          // a HUMAN must pay — agents can't enter a card
  "buy_url": "https://ibluetext.com/portal/billing.php" }

Agents: on a 402, stop and tell your human to pay at buy_url, then resume. Buy credits · Subscribe a sending line.

Check your wallet + per-line daily usage anytime: GET /api/v1/balance → credits, free-trial + free-daily lookups remaining, and each line's new-contact / non-replier counts. Poll it to warn before $0 or a daily cap.

Sending limits

To keep your number safe from carrier/Apple bans, each line is capped per customer-local day (resets 4am your time):

Webhooks

Get replies and delivery events pushed to your server in real time. Set a webhook URL under Settings (coming online with your line). Example payload:

{ "event": "message.reply",
  "from": "+18135550142",
  "body": "Yes please!",
  "received_at": "2026-06-17 14:05:00" }

Opt-outs

Compliance is automatic. Any reply containing STOP, UNSUBSCRIBE, CANCEL, QUIT, or END adds that number to your opt-out list, and the API will refuse to send to it (409). This is required under the TCPA — see our Terms.

Conversations API

Pull full two-way transcripts so your own app or AI agent can read what each contact said and act on it (e.g. update a CRM, or add/remove a listing on another site). iBlueText returns the raw in/out messages — your side does the judging.

GET/api/v1/conversations

Query params: phone (one conversation), since (ISO time — only conversations with newer activity, for incremental polling), limit (default 200, max 1000), include_no_reply=1 (also include contacts who never replied; default is repliers only).

curl "https://ibluetext.com/api/v1/conversations?limit=200" \
  -H "Authorization: Bearer $IBT_KEY"

{
  "count": 1,
  "conversations": [
    {
      "phone": "+18139188356",
      "company_name": "FinSanity Fishing Charters",
      "link": "https://beercanisland.com/c/0XCtDU1a",
      "fields": { "company_name": "FinSanity Fishing Charters", "link": "https://beercanisland.com/c/0XCtDU1a" },
      "opted_out": false,
      "last_activity": "2026-07-11 19:39:04",
      "messages": [
        { "dir": "out", "body": "Hi is this FinSanity Fishing Charters?", "at": "2026-07-11 19:35:00", "channel": "sms", "status": "sent" },
        { "dir": "in",  "body": "Yes, it is", "at": "2026-07-11 19:37:17" },
        { "dir": "out", "body": "Here's your link: https://beercanisland.com/c/0XCtDU1a", "at": "2026-07-11 19:39:40", "channel": "sms", "status": "sent" }
      ]
    }
  ]
}

Each conversation carries the contact's uploaded fields (including company_name and link), an opted_out flag, and the ordered messages (dir is in or out). Generate a key under Integrations → API keys.

AI auto-replies

Turn on Inbound AI and your line answers incoming texts automatically — trained on your business, and optionally on per-contact data you provide. Two modes:

Give the AI a per-contact database

When you send a campaign, include a CSV with a phone column plus any fields you want. Each row is stored against that number and handed to the AI when the person replies:

company,phone,loan_amount,rate,due_date,link
Reel Deal LLC,+18135550142,$45000,6.9%,Aug 1,https://you.com/portal/abc123
Salty Dog LLC,+17275550199,$12000,8.4%,Sep 15,https://you.com/portal/def456

Now if +18135550142 texts "what's my rate and my link?", the AI replies with 6.9% and that contact's link. Guide it from your Instructions, e.g. "If a client asks about their loan, share the amount, rate, and due date from their info; if you don't have a detail, say a teammate will follow up."

Safety: replies never cross contacts

Every reply is scoped to the exact E.164 phone number that texted in — the model only ever receives that one contact's fields, so John can't get Jane's data. The AI is also instructed never to invent account details (amounts, rates, balances, links); if it doesn't have a value on file, it defers to a human instead of guessing. STOP/opt-outs are never answered.

CRM & integrations

Because everything runs over a standard REST API, iBlueText drops into any stack:

Native one-click connectors are rolling out — tell us which you need at support@ibluetext.com.

Errors & limits

Errors return a JSON error string with a standard HTTP status:

401 invalid/missing key   ·   402 out of credits / no line
400 bad request           ·   404 not found
409 recipient opted out   ·   429 rate limited

Up to 50,000 numbers per lookup request. Sends are paced by your line's safe throughput. Need higher volume? Add more lines.

Get your API key — start free →