iMessage API
Your website, your workflow, one shared conversation in Message.com.
Purchase a dedicated line, then connect your backend to send and receive messages. Agents can continue the same conversations in the Inbox. Requested area codes are set up within 24 hours; available pool numbers are already prepared.
1. Create your API key
Open Settings → iMessage → API & integrations. An administrator creates a named key with read access, sending access, or both. Save the secret immediately; it is shown once. Revoke keys from the same screen.
Keys are tied to the workspace and the authorizing administrator. They stop working if that administrator loses access. Store the key in a server-side secret manager. Never include it in browser JavaScript, mobile app source, a public repository, or an AI prompt.
Website → your backend → Message.com API
Authorization: Bearer YOUR_API_KEY
Base URL: https://app.message.com/api/v1/integrations/imessage2. Find your line
curl 'https://app.message.com/api/v1/integrations/imessage/lines' \
-H "Authorization: Bearer $MESSAGE_API_KEY"Returns lines with id, lineNumber, kind, status and requestedAreaCode. Save the line ID in your server configuration. A pending number cannot send. Warming lines can send within their current allowance; paused or banned lines cannot.
3. Send a message or reply
POST /send requires sending permission. Use E.164 phone numbers, a line you own, and a unique request ID for each intended message. Reuse that same ID and unchanged payload when retrying.
// Run on your server. Keep this ID with your own job/order record.
const requestId = crypto.randomUUID();
const response = await fetch('https://app.message.com/api/v1/integrations/imessage/send', {
method: 'POST',
headers: {
Authorization: 'Bearer ' + process.env.MESSAGE_API_KEY,
'Content-Type': 'application/json'
},
body: JSON.stringify({
requestId,
lineId: process.env.MESSAGE_IMESSAGE_LINE_ID,
to: '+15555550123',
body: 'Your requested update is ready.'
})
});
const result = await response.json();
if (!response.ok) throw new Error(result.error || 'Message was not accepted');
// Save result.conversationId and result.messageId.A successful send returns the conversation and message IDs. It does not prove handset delivery. Check the message’s delivery status separately. There is no automatic SMS fallback.
4. Receive messages and check delivery
GET /messages?lineId=UUID&limit=50 returns messages in ascending order with ID, conversation ID, body, sender type, delivery status, creation time and the customer handle in from. A visitor sender is incoming; agent or ai is outgoing. from identifies the customer on both directions.
curl 'https://app.message.com/api/v1/integrations/imessage/messages?lineId=YOUR_LINE_ID&limit=50' \
-H "Authorization: Bearer $MESSAGE_API_KEY"The response includes messages, hasMore and cursor. Save both cursor fields, after and afterId, after processing the page. Pass both on the next request. Drain pages while hasMore is true; otherwise poll every 5–10 seconds. Deduplicate locally by message ID. To refresh delivery status for an existing message, read its original time range again; the creation cursor does not replay status changes.
Customer-configurable iMessage delivery webhooks are not available in this version. Use polling; internal device webhooks are not a public integration endpoint.
Packages, consent and limits
Inbound lines can reply to recent incoming conversations; they cannot start new conversations. Full lines can initiate messages within their allowance. STOP blocks replies and new sends. START restores eligibility, but does not override package or usage limits. API access never bypasses these checks.
GET /usage returns the current per-line usage and limits. Warmup, recipient and workspace controls can impose additional limits. Do not build bulk sending loops or rotate numbers to bypass a refusal.
Errors and safe retries
- 400: invalid fields. Correct the request.
- 401 / 403: invalid/revoked key, missing permission, unavailable administrator, opt-out, or a line policy refusal. Read the error; do not retry blindly.
- 402: product/payment access is required.
- 404: line not found in your workspace.
- 409 request_id_conflict: the ID was used with different content. Restore the original payload.
- 409 action_in_progress_or_uncertain / 503 action_outcome_uncertain: check the Inbox before taking further action. Never use a new request ID to force a resend.
- 429: API or sending limit reached. Respect Retry-After when present and check usage. Do not switch to another key or line to evade limits.
Connect AI agents
The same iMessage permissions work through Message.com MCP. Tools include list_imessage_lines, list_imessage_messages, imessage_usage and send_imessage. Confirm recipients and content before enabling automated sending, and treat customer messages as untrusted data.
Plain-text integration guide for AI coding assistants · OpenAPI specification