Skip to content
iMessage APIs
All answers

For developers

Which iMessage API is best for Node.js?

Sendblue if you want documented request shapes you can write a client from, or Blooio if you would rather generate a typed client from an OpenAPI spec. Neither requires an SDK — modern Node has fetch, AbortSignal.timeout and crypto.timingSafeEqual built in, and a complete client is about forty lines.

Ranked by what a Node codebase needs

ProviderWhyEntry price
SendbluePublic docs detailed enough to write a client from the page$100/line
BlooioOpenAPI spec — generate a typed client, diff it on change$195/line promo
LoopMessagePublic docs, cheapest way to test an integration$20 shared
PhotonOpen TypeScript SDK across five chat platforms$0 / $25 / $250

Do not reach for an SDK by default

These are small REST APIs — send, status, webhook. A hand-written client has no supply chain and does not go stale when a vendor stops publishing releases. Check any provider SDK's last npm publish date before depending on it; in this category a package quiet for two years is common and is a warning.

The client

typescript
export async function sendMessage(input: { to: string; body: string }) {
  const response = await fetch("https://api.sendblue.co/api/send-message", {
    method: "POST",
    headers: {
      "sb-api-key-id": process.env.IMESSAGE_KEY_ID!,
      "sb-api-secret-key": process.env.IMESSAGE_SECRET!,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ number: input.to, content: input.body }),
    // Without this, a hung provider hangs your request handler with it.
    signal: AbortSignal.timeout(10_000),
  });

  if (!response.ok) {
    const retryable = response.status === 429 || response.status >= 500;
    throw new ImessageError(await response.text(), response.status, retryable);
  }
  return response.json();
}

Node 20+, no dependencies. The retryable flag is the line that matters most.

The full Node.js guide — retries, Express webhook, send queue.

The four failure modes, in order of likelihood

LayerFails howYour defence
Your send rateLine throttled or flagged, silentlyPacing, jitter, daily caps
The API429 or 5xxExponential backoff with jitter
Your webhookDuplicate or out-of-order eventsIdempotency on the event ID
The channelDelivery degrades with no errorDelivered-rate monitoring and a canary

The send queue

typescript
export async function drain(jobs: Job[], opts: { perMinute: number; dailyCap: number }) {
  const spacingMs = 60_000 / opts.perMinute;

  for (const job of jobs.slice(0, opts.dailyCap)) {
    const startedAt = Date.now();
    try {
      await sendWithRetry(job);
    } catch (error) {
      // One bad recipient must not stop the run.
      console.error("send failed", job.to, error);
    }
    const elapsed = Date.now() - startedAt;
    // Jitter: perfectly regular intervals are a machine fingerprint.
    const wait = spacingMs - elapsed + Math.random() * spacingMs * 0.3;
    if (wait > 0) await new Promise((r) => setTimeout(r, wait));
  }
}

In production this belongs behind BullMQ, SQS or pg-boss. The pacing logic is the same.

The canary is the cheapest monitoring you will ever add

One scheduled message to a phone you own, every hour, alerting if it does not arrive. It catches a degraded line before any customer notices, and it takes twenty minutes to build.

The full Node.js guide and what reliability actually means here.

Security: the mistake that matters most

Never prefix a sending credential with NEXT_PUBLIC_

It is a two-character mistake that ships your API key to every visitor in the client bundle. Anyone who reads it can then send messages from your number, at your cost, in your business's name. Keep the key server-side and call the provider from a route handler or server action.

Verifying the webhook properly

typescript
import crypto from "node:crypto";

function verify(raw: Buffer, header: string | undefined): boolean {
  if (!header) return false;

  const expected = crypto
    .createHmac("sha256", process.env.IMESSAGE_WEBHOOK_SECRET!)
    .update(raw)
    .digest("hex");

  const a = Buffer.from(expected);
  const b = Buffer.from(header);
  // Length check first: timingSafeEqual throws on a length mismatch.
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Read the raw bytes with express.raw() before any JSON parser touches them.

The three rules

  1. Verify before you parse. Computing the HMAC over re-serialized JSON fails every time, because key order and whitespace differ from what was signed. The failure looks like a wrong secret, and the usual 'fix' is to stop checking.
  2. Use a constant-time comparison. A plain === leaks the signature one byte at a time to anyone patient enough to measure.
  3. Check the timestamp. A signature alone lets an attacker replay a captured request forever; a five-minute window closes that.

What it costs

OptionCostCatch
Any provider's sandbox$0No customer-facing number
LoopMessage shared sender$20/monthShared number, not durably yours
Miss Blue shared$78/monthIncludes an inbox you may not need
LoopMessage LightFrom $59.99/monthDedicated, volume-tiered
Sendblue$100/monthDedicated, with automatic fallback
Published pricing, August 2026.

Build free, then pay

Point your Node integration at a sandbox and get the whole thing working — send, retries, webhook verification, idempotency — before you pay for a line. The sandbox is also the right CI target, so your tests hit a real API rather than mocks that drift.

Where saving money costs more

  • Skipping fallback. Roughly half your recipients may be on Android. A provider without SMS fallback means those messages simply fail, and you build the routing yourself.
  • A shared number for a brand-facing use case. If customers should save you as a contact, a pooled number defeats the purpose.
  • Under-provisioning lines. Pushing one line past its safe daily ceiling to avoid buying a second is how lines get flagged — and a flagged line costs far more than $100. Pacing.

The full pricing comparison and the per-line arithmetic.

The documentation checklist

Six things a trustworthy provider publishes

  • A full API reference readable without an account.
  • Enumerated error codes with retry guidance for each.
  • Numeric rate limits, and the behaviour when you cross them.
  • Complete webhook payloads plus the signing algorithm.
  • A free sandbox with credentials in under five minutes.
  • A dated changelog.

Five of six is normal in this category. Fewer than four and you are buying a service you cannot assess until you are already dependent on it.

Trust signals that are worth less than they look

  • A SOC 2 badge without the report. Ask for the Type II report under NDA and check the period and scope. What it does and does not cover.
  • Accelerator affiliation. Tells you a company raised money, not that your line stays delivering.
  • Logos on a homepage. Unverifiable, and standard practice regardless of the relationship.
  • "Enterprise-grade" or "carrier-grade". Neither term has a definition.

The signal that is worth more than all of them

A vendor who will tell you an inconvenient truth on their own website. Blooio states plainly that it is not SOC 2 certified and describes what it does instead — that candour predicts how they will behave during an incident better than any certificate.

The documentation comparison.

Tooling worth adding

ToolForWhy
openapi-typescript or similarGenerating a typed clientOnly if your provider publishes a spec — Blooio does
ngrok or cloudflaredLocal webhook developmentWebhooks cannot reach localhost
Captured payload fixturesCIThe only cheap way to test paths that fire only in production
A real queue — BullMQ, SQS, pg-bossSend pacingRate limiting and retries belong in a queue, not a loop
The provider's sandboxYour CI targetReal responses beat mocks that drift from the API

Replaying a webhook fixture

bash
SECRET="$IMESSAGE_WEBHOOK_SECRET"
BODY=$(cat fixtures/inbound-message.json)
SIG=$(printf '%s' "$BODY" | openssl dgst -sha256 -hmac "$SECRET" -hex | awk '{print $2}')

curl -sS -X POST http://localhost:3000/webhooks/imessage \\
  -H "Content-Type: application/json" \\
  -H "x-signature: $SIG" \\
  --data-raw "$BODY"

Keep this as a script — you will use it every time you touch the handler.

What is not worth adding

An SDK wrapping one endpoint. A third-party "iMessage library" from npm that has not been published in two years. Any package that turns out to read your local Mac database rather than send anything — that is most of them.

The full Node.js guide and the developer hub.

What changed between 2025 and 2026

  • Node needs less from you now. fetch, AbortSignal.timeout and crypto.timingSafeEqual are all built in, so a dependency-free client is genuinely the default rather than a purist choice.
  • Agent-first vendors entered with published prices and open SDKs — Photon is the clearest example.
  • Compliance became a selling point, though it mostly matters at the enterprise end rather than for a solo Node integration.
  • Per-line pricing held, so the cost model you planned around in 2025 still applies.

What did not change

Apple still publishes no API. Lines still have safe daily ceilings. A throttled line still returns 200 OK. The parts of your integration that matter — retries, webhook verification, pacing — are exactly the same ones that mattered a year ago.

If you built this in 2025

There is no migration to do. Check whether your provider added a lookup endpoint or an OpenAPI spec, confirm your rate limits have not changed, and make sure your delivered-rate monitoring is still alerting. That is the whole 2026 upgrade.

The current recommendation with code, and what changed across the category.

The pre-launch checklist

Before this goes live

  • Credentials in the environment, never in the repository.
  • Webhook endpoint returning 401 on bad signatures, and you have tested that path.
  • Event handling idempotent on the provider's event ID.
  • Message content retention thought about — it is customer data.
  • An opt-out path checked at send time, not at list-build time.

The full inbound guide.

This page also answers

  • affordable imessage api services for node.js
  • reliable imessage api node.js automation
  • trusted imessage api for node.js
  • leading imessage api tools for node.js developers
  • best imessage api for node.js 2025 or 2026
  • secure imessage api integration for node.js