Skip to main content
A BYOD line runs on a device that you or your user own: a Mac paired with an iPhone, or an Android phone. The bridge app, installed on that device, sends and receives for the line. This page shows how to create a BYOD line: you issue an activation code, the user enters it in the bridge app, and a new line appears on your account. Read it when your users bring their own devices.

BYOD slots

Whether you can issue an activation code depends on your account.
  • Direct account. You need a free BYOD slot. No operation that an API key can call buys one: buy slots in the iSnap dashboard, by card. See Accounts. A slot counts once iSnap has recorded its payment, and the API does not bound the delay between a successful payment and that record. Each BYOD line of your account that is not terminated uses one slot, a suspended line included. A slot counts until the end of the period it is paid for, even while its payment is past due and after its cancellation is scheduled.
  • Wholesale partner. You need no slot. Your BYOD lines are counted on your monthly invoice, and each line gets its anniversary when it is paired.
A direct account with no slot at all receives 402 payment_required from POST /v1/byod/pair. A direct account whose slots are all used receives 404 no_slot_available. When your slots stop covering a BYOD line, that line ends without a call from you: see Ends you do not request.

Before you pair

  • The bridge app for macOS runs on macOS 14 or later, on the Mac that is paired with the iPhone of the line.
  • The Mac must grant the bridge app the two permissions it asks for: Full Disk Access, to read messages, and Automation, to control Messages. Without Full Disk Access, the line can neither send nor report what it receives.
  • To send SMS or RCS, the iPhone forwards its text messages to the Mac: see Services and fallback.
  • The bridge app for Android is offered only when GET /v1/apps reports available: true for android.

Pairing a device

1

Check that an installer is available

Call GET /v1/apps. It needs no credential. The response has one entry for macos and one for android, each with url, version, version_status and available.Offer a platform to your user only when its available is true. When it is false, no installer is offered for that platform and its url returns 404.
2

The user installs the bridge app

The user installs the bridge app from the url of their platform: on their Mac, which is paired with their iPhone, or on their Android phone. The app decides the kind of line: the bridge app for macOS creates an iMessage line (byod_imessage), and the bridge app for Android creates an Android line (byod_android). The request has no field for the platform.
3

Issue an activation code

Call POST /v1/byod/pair with an API key. The code is valid for 5 minutes: issue it when the bridge app is installed and open. The only field of the body is metadata, and it is optional. Any other field, such as device_type or device_name, returns 400 validation_failed.The response is 201 with these fields:
4

The user enters the code

The user enters the activation code in the bridge app. A code that is unknown, already used or expired is refused in the bridge app. The refusal is not returned to your backend: issue a new code.
5

A new line appears on your account

When the user enters a valid code, iSnap creates a new BYOD line on the account that issued the code. The line is active immediately, and it carries the metadata that you sent with the code.iSnap sends line.connected with data.line, data.device_session_id and data.connected_at. connected_at equals the activated_at of the line. To find the line without the event, call GET /v1/lines/my and match the metadata that you sent. A line-scoped key does not see the new line in GET /v1/lines/my, since the line is not in its list: read the line id from the event, or list with a key that has no list of lines.
6

Read the number of the line

phone_number is "" until the device reports its number. No event announces the number when it arrives: read the line with GET /v1/lines/{id} until phone_number is not empty.

Issue an activation code

Find the new line and its number

The activation code is a credential

Whoever enters an activation code in the bridge app within its 5 minutes creates a line on your account. Show the code only to the user who pairs the device, and do not copy it into logs, tickets or other tools.
A code works once. To pair another device, issue another code. POST /v1/byod/pair does not honor Idempotency-Key: a repeated call issues another activation code. Retry a write only on an operation that honors Idempotency-Key, with the key of the first attempt. The SDK retries this call on its own after a failed attempt, and then returns the code of the last attempt: give the user the code that you received.

One pairing, one line

Every successful pairing creates a new line, with a new id. No operation moves an existing BYOD line to another device. When a user replaces their Mac or their phone, pair the new device, which creates a new line, then terminate the old line. Until you terminate it, the old line keeps its slot: a direct account whose slots are all used receives 404 no_slot_available when it issues the code, and terminates the old line before it pairs the new device.

Ending a BYOD line

POST /v1/lines/{id}/terminate ends a BYOD line and frees its slot. POST /v1/lines/{id}/release does not apply to a BYOD line: it only gives back a line that you have reserved from the marketplace. Terminate describes what a termination does to the line, its messages and its billing, and Ending a line lists the other ways a line ends.

Versions of the bridge app

GET /v1/apps reports, for each platform, the version of the bridge app and a version_status that explains it. version is not null exactly when version_status is published. bridge_version, in the response of POST /v1/byod/pair, is a separate value that iSnap sets. It can differ from the version that GET /v1/apps reports for the same platform: do not compare the two.

Health and connectivity

A BYOD line reports the state of its device. GET /v1/lines/{id}/health returns that state, and the events line.offline, line.degraded, line.capability_changed and line.connected are sent for a BYOD line. See Health, Connectivity events and Attention. On a BYOD line, reactions, typing indicators, read receipts, effects, threaded replies, voice notes, lookups and SMS or RCS to non-iMessage recipients depend on the device: read runtime_capabilities on GET /v1/lines/{id}/health before you rely on one. See Device features.

Metadata

The metadata of POST /v1/byod/pair becomes the metadata of the line that the pairing creates. It contains at most 20 keys and 8,192 bytes once serialized. Every read of the line returns it, and so does every line.* event. Change it afterward with PATCH /v1/lines/{id}: see Metadata. Line metadata is readable by anyone who holds the line id. Never put personal data or secrets in it: refer to your user by an id of your own.

Events

Pairing sends one event: line.connected, when the device completes pairing. No event announces the number of the line when the device reports it, and no event is sent when an activation code is issued. The line events have limits: see What events do not announce. To know your BYOD lines and their state, read them with GET /v1/lines/my and GET /v1/lines/{id}/health.

Keys and accounts

  • Test keys. An isnap_test_ account key is not a separate test environment: it acts on the same account, lines and billing as an isnap_live_ key. An activation code issued with a test key creates a real line. See Test keys.
  • Line-scoped keys. The list of lines of a line-scoped key is not applied to POST /v1/byod/pair: such a key can issue activation codes.

Errors

The refusals of each operation are on its reference page: GET /v1/apps and POST /v1/byod/pair. The errors that every operation shares are in Errors.

Personal data

The line object, and the line object inside line.connected, carry phone_number. On a BYOD line, it is the number of the device that the user paired. Request it only when you need it. Do not copy it into logs, tickets or other tools. Refer to your user by an id of your own.