Skip to main content
After this guide, people you enroll can open Messages on an iPhone or Mac, text a number Lua assigns, and talk to your agent with native markdown, attachments, and link previews. iMessage is delivered through Photon; the platform creates and owns the Photon project for your agent, so there is nothing to obtain from Apple. The channel is set up in the admin dashboard or over the admin REST API; there is no CLI command. Verified against lua-cli 3.33.0. Before you begin
  • An agent in the admin dashboard, or an API key with the channels:manage scope on it.
  • The phone numbers of the people who will text the agent. On the shared tier, only enrolled numbers can reach it.
1

Dashboard: add the iMessage channel

Add a channel of type iMessage to the agent (POST /admin/agents/<agentId>/channels with { "type": "imessage" }; no other fields). The platform creates a Photon project named after the agent, enables iMessage on it, registers a signed webhook, and stores the credentials. The call is idempotent: an agent has at most one iMessage channel, and a second request returns the existing one.The channel starts on the shared tier, a pool of rotating sender numbers. A dedicated tier with your own number exists in the data model but isn’t provisioned yet.
2

Dashboard: enroll a recipient

Enroll each person with POST /admin/agents/<agentId>/channels/imessage/users and { "phoneNumber": "+15551234567" } (optionally firstName, lastName, and msg, a pre-filled first message). The response carries assignedPhoneNumber, the pool number that person texts, and redirectUrl, an https link that redirects into Messages addressed to that number (with the pre-filled text when you passed msg). Share the link, or build your own sms: link from assignedPhoneNumber.The conversation is inbound-first on purpose: the person sends the first message, so Messages shows no junk warning. GET …/channels/imessage/users lists enrollments with the tier, the cap, and the count; DELETE …/channels/imessage/users/<userId> removes one, after which that person can no longer text the agent.
3

Verify

Text the assigned number from an enrolled device. The agent shows a typing indicator while it works and replies in the same thread; Lua.request.channel inside your tools is imessage. Confirm the turn with lua logs --type agent_response.

Channel behavior

The model is told it is in an iMessage conversation and to keep replies short. A person who texts from a phone number and later from an Apple ID email resolves to two different end users. Every thread with a person shares one conversation.

Limits

Troubleshooting

Enrollment and listing need the channel to exist. Add the iMessage channel to the agent, then enroll recipients.
The shared pool allows 10 enrolled recipients, and the provider refuses the eleventh. GET …/channels/imessage/users returns tier, cap, and count so you can check before adding; free a slot with DELETE …/channels/imessage/users/<userId>.
Attachments are fetched by the platform before sending. The URL must be https, publicly reachable without redirects, and at most 25 MB; otherwise the attachment is skipped and the rest of the reply is still delivered.

Next steps

Response formatting

What each component becomes on iMessage.

Identify users

Recognize the same person across channels.

About channels

Inbound and outbound channel vocabularies.

SMS and phone numbers

Plain texting for everyone else.