Inbound-first is the decision that matters
The single most important design call is whether users text you first or you text users. Inbound-first integrations never surface the “Report Junk” banner that Apple shows on every message from an unknown number. Outbound-first integrations do, and after a couple of unanswered messages it tends to get tapped. How to make inbound-first work in practice:- Pre-populate the first message. Ship
sms:+1...&body=Hey!deep links so tapping opens Messages with text pre-filled. Zero friction, and the user is the one who hits send. - Share a contact card early. Push a native iMessage contact card (or a
.VCFfor Android) shortly after the first exchange. Once they save it, you’re a known contact and “Report Junk” is gone for good.
Capacity
Two quotas govern how much traffic a deployment can carry. They’re enforced limits.
Use these ranges as starting points when you assign users to lines:
These ranges are operating recommendations, not hard limits. A line may support more than 1,000 users. Total user count is only one part of capacity, though. A line can still hit activity limits when many existing users become active at once or many new users arrive within a short time window.
Always spread users across multiple lines. We strongly recommend enabling Photon’s smart routing and auto-scale so the system can distribute users and traffic spikes automatically. When a server hits 70-80% utilization, stop assigning new users to it. When the whole pool reaches that point, add capacity. On the Business plan, auto-scale handles the second step automatically.
New inbound contacts
Apple’s APNs service limits inbound activity from new contacts. If you expect an influx of new inbound conversations, distribute those contacts across multiple lines instead of directing everyone to one line. A short burst can affect deliverability even when the total number of users is within the recommended range.What gets a line flagged
Because Apple filters on behavior, the same five patterns account for nearly every flag we see:- Burst sending: 100+ messages from one line in a tight window
- No conversation: broadcasting without exchange
- Hammering non-responders: more than 2–3 follow-ups
- Cold outreach: texting people who never opted in
- Off-hours sending: 3am messages signal automation
Do
- Design for inbound-first. Users text you, not the other way around.
- Pace messages naturally. Don’t fire several within seconds. Bursts of 100/min look automated because they are.
- Make outreach conversational. If you need to push an update (digest, accountability ping), open with a question and wait: “Ready for your update?”
- Share a contact card after the first exchange. Once saved, the “Report Junk” surface is gone.
- Round-robin new users across lines. Spread load before any one line stands out.
- Enable smart routing and auto-scale. Let Photon distribute growth and traffic spikes before a line becomes overloaded.
- Maintain a strong response rate. Respond consistently and build flows that encourage users to send at least three messages per conversation.
- Watch the dashboard. When a line goes Flagged, review what the agent was doing in the hour before — the cause is almost always there.
Don’t
- Push past the per-server quota. Add capacity; horizontal scaling is the design.
- Include links or media in the first message. Apple suppresses link-clicking until a reply lands. Ship a text-only opener built to get a response.
- Leave fallback lines dormant. Apple deactivates lines with no traffic for ~2 months. Every line you keep around needs some traffic.
- Bombard non-responders. Cap at 2–3 follow-ups, spaced across days, not hours.
- Segment Android users onto separate lines. Spread them through the pool — they may be your power users.
- Use iMessage for cold outreach. Cold belongs on A2P channels (Twilio etc.). iMessage is for warm conversations.