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.

  1. 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
  2. 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
  3. 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

    1. Awaiting sender

      We are assigning a line to the connection.

    2. Activate iMessage line

      The sender is assigned. Activate it when you are ready.

    3. Configured

      The line can send and receive for your project’s keys.

  4. Create an API key

    In API Keys, create a key, allow it your line and grant sendMessages and readMessages. Add writeWebhooks if 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="…"
  5. 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_secret exactly 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"]
      }'
  6. 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.received with 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.

  7. Reply

    Answer in the chat the message came from. 202 Accepted means the reply is queued; message.delivered or message.failed follows 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-signature with 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_key and the person still receives one message. A different body under that key answers 409.

  • Act on delivery events

    Treat message.delivered as done and message.failed as 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.

Ready for step one?