Skip to main content
A single line has a ceiling (see Limits). The way to scale beyond it is to add more lines and spread your users across them.

When to add a line

Add a second (or third, or tenth) line when:
  • Sustained traffic on an existing line is approaching the per-line numbers.
  • A single-line outage would be unacceptable — you want a line that can take over if one gets flagged or its underlying Apple ID needs to re-auth.
  • You’re running multiple distinct products or brands and want clean separation between them.

Spread users across lines

Each user should be assigned to one line, and the assignment should be stable: the same user always lands on the same line so their conversation history stays continuous. How you assign users is up to you. The send API requires you to specify from on every call, so the routing decision lives in your code:
import { createClient } from "@messages-dev/sdk";

const client = createClient();

// Pick a line for this user. Whatever logic you use, keep it stable
// so the same user always ends up on the same line.
const line = pickLineForUser(userId);

await client.sendMessage({
  from: line,
  to: userPhone,
  text: "Hey!",
});
A few practical notes:
  • Keep traffic balanced. If one line carries 80% of users, you’ve still only got the throughput of that one line.
  • Monitor each line independently. The outbound:inbound ratio, daily volume, and unanswered-message counts from Limits apply per line, not aggregated across your account.
  • Treat new lines as new lines. A line that’s been in use for 6 months isn’t comparable to one provisioned yesterday. Ramp new ones up gradually.
You can scope an API key to specific lines using the lineIds field when creating the key. This is useful if different parts of your stack should only be able to send from a subset of lines.

Backup lines via contact cards

A contact card can carry more than one phone number. If you deliver a vCard with both your primary line and a backup line, the user saves both to their contacts. If your primary line is ever throttled, unreachable, or being warmed back up, the user already has the backup saved and can text it directly:
await client.sendContactCard({
  from: "+15550000001",
  to: userPhone,
  firstName: "Acme",
  lastName: "Support",
  phones: [
    { type: "cell", value: "+15550000001" }, // primary
    { type: "main", value: "+15550000002" }, // backup
  ],
});
Send this once during onboarding (or any other moment where it’s natural for the user to save your contact). From then on, both numbers live in their address book and they can fall back to the backup if your primary line goes quiet. See Contact cards for the full vCard reference.