Provider packages
- Cloud: @spectrum-ts/imessage
- Local: @spectrum-ts/imessage-local
Authenticates with Spectrum Cloud and connects to managed iMessage infrastructure via gRPC. Supports sending, receiving, typing indicators, reactions, and replies. Group creation and inbound group-change events require a dedicated line.With automatic discovery, tokens are renewed at 80% of their TTL. This requires Spectrum discovers all cloud lines owned by the project and renews their tokens automatically. For advanced routing, you can instead provide a subset of the project’s cloud clients:Explicit clients let you control which cloud-owned lines this SDK instance subscribes to. They still use the cloud package. Their tokens are not renewed by the SDK, so you are responsible for keeping them current; most applications should use automatic discovery.
projectId and projectSecret on the Spectrum() call:Line model
Cloud mode routes your messages through phone numbers, also called lines, provisioned by Spectrum. Which lines you get depends on your plan, and the difference is mostly invisible to end users.
DM delivery is identical across both cloud line models. The developer-facing differences are sender-number allocation and group support.
Auto-scale
When traffic to a dedicated line approaches its per-line capacity, Spectrum can automatically provision an additional line so deliverability isn’t affected. Auto-scale is an opt-in feature on the Business plan. Enable it in your project settings if you’d rather not get paged when a line saturates.When line changes reach a running app
The SDK learns about your lines from the credentials it mints, and it re-mints them on a schedule — so a line provisioned (or deprovisioned) while your app is running is picked up at the next token renewal, not immediately. Until that renewal lands, a newly provisioned line is invisible to the process: it receives no inbound messages, andspace.create() cannot route through it. Messages sent to it in that window are not delayed, they are not delivered to your app at all. Restart the process if you need a new line to take effect right away.
On dedicated lines, two routing behaviors change the moment a second line appears, whether that happens at startup or mid-run:
space.get(chatGuid)starts requiringparams.phone. With exactly one dedicated line the SDK can infer it; with two or more it cannot.space.create()without an explicitphonestarts picking at random from the larger set.
These are Spectrum Cloud features. With
@spectrum-ts/imessage-local, you
provide the Messages account on the Mac and managed-line concepts do not
apply.Quotas
Space types
iMessage spaces carry atype field, either "dm" or "group", and a phone field indicating which phone number the conversation is routed through. Both are accessible through narrowing:
User properties
iMessage users carry optional platform-specific fields when resolved through narrowing. These are available when the platform has sender details for the user:message.sender after narrowing:
Creating conversations
Resolve users by phone number or email, then create a space withspace.create(...):
space.get(id):
params.phone, as covered in per-phone routing.
DM creation works with the cloud package. The local package can construct a
deterministic DM reference, but it cannot create a group because the local
Messages database does not expose chat creation.
Group creation requires a dedicated line. In shared-pool mode, passing multiple users to space.create() throws an . You can use space.get(chatGuid) to reference an existing group, but shared mode still does not receive membership or metadata changes from the group-event stream.
Per-phone routing
If your account has multiple dedicated phone numbers, you can pin a conversation to a specific line by passingphone as a space parameter:
Per-phone routing applies to dedicated lines on the Business plan only. On shared-pool plans the
phone parameter is ignored because all conversations route through the shared pool automatically.