Quickstart
From sign-up to your first reply.
Seven steps, one of them ours. Every Messages.org line works the same way: someone texts it, your server gets a signed webhook, and your agent answers with one request.
-
Create your account
Open the Console and choose Create an account on the sign-in page. Then name your organization: it holds your projects, iMessage lines and API keys, and you can invite teammates once it exists.
You will need
- An email address you can confirm
- A name for your organization, usually your company or team
-
Create a project
A project keeps its own connections, API keys, webhook endpoints and activity record, separate from every other project. Choose Create project in the Console.
Once the project has a connection, its Overview opens a simulated sandbox where you can try the API before a real line is ready. Nothing in it reaches a real phone.
Simulated sandbox
- 5test recipients
- 100messages
- 7days
-
Done by Messages.org
Get a line
In Connections, choose Add connection. A person at Messages.org assigns an iMessage sender to it, and the connection shows Awaiting sender until then. When the sender appears, choose Activate iMessage line and add a reference of your own, such as an order or ticket number.
Assignment is not instant. If it is taking longer than you expected, tell us.
What the Connections page shows
- Awaiting sender
We are assigning a line to the connection.
- Activate iMessage line
The sender is assigned. Activate it when you are ready.
- Configured
The line can send and receive for your project’s keys.
- Awaiting sender
-
Create an API key
In API Keys, create a key, allow it your line and grant
sendMessagesandreadMessages. AddwriteWebhooksif you will manage webhook subscriptions from code. A key starts with no permissions, expires after 7, 30 or 90 days, and is shown once.Your server’s environment # Shown once in the Console. Keep it server-side. export MESSAGESORG_API_KEY="…" -
Point a webhook at your server
Add the endpoint in the Console’s Webhooks page, or create it with the API. Either way the response carries the
signing_secretexactly once; you need it to verify every event.POST /v3/webhook-subscriptions curl https://api.messages.org/v3/webhook-subscriptions \ -H "Authorization: Bearer $MESSAGESORG_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "target_url": "https://your-app.example/messages", "subscribed_events": ["message.received", "message.delivered", "message.failed"] }' -
Text your line
From your own phone, send an iMessage to the line. People write first: a line does not message strangers, so every conversation starts with someone who chose to write. Your endpoint receives
message.receivedwith the chat to answer in.message.received POST /messages HTTP/1.1 webhook-id: 3f6c1d2e-8a4b-4c7d-9e0f-1a2b3c4d5e6f webhook-timestamp: 1794594000 webhook-signature: v1,K7hYq0b0Ue3m… { "event_type": "message.received", "data": { "chat": { "id": "5b0e4c1a-93d2-4f1e-8c57-2e6a90d4b7f3" }, "sender_handle": { "handle": "+14155550123" }, "parts": [{ "type": "text", "value": "Hi! Can I bring my bike in Saturday morning?" }], "service": "iMessage" } }Abridged. The full event also carries delivery timestamps and the project it belongs to.
-
Reply
Answer in the chat the message came from. 202 Accepted means the reply is queued;
message.deliveredormessage.failedfollows as a webhook.POST /v3/chats/{id}/messages curl https://api.messages.org/v3/chats/$CHAT_ID/messages \ -H "Authorization: Bearer $MESSAGESORG_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "message": { "parts": [{ "type": "text", "value": "Saturday at 9:30 is open. Shall I book it?" }], "idempotency_key": "booking-reply-7f3c" } }'
Before real people write to you
Verify every webhook
Check
webhook-signaturewith any Standard Webhooks library and reject events older than five minutes. The verification example is a dozen lines of Node.js.Retry with the same key
Resend a failed request with the same
idempotency_keyand the person still receives one message. A different body under that key answers 409.Act on delivery events
Treat
message.deliveredas done andmessage.failedas a reason to try another way. 202 only means queued.STOP is enforced for you
When someone replies STOP, sends to them answer 403 with code 2024 until they write to the line again. You do not have to build it.