Skip to main content

Documentation Index

Fetch the complete documentation index at: https://messages.dev/docs/llms.txt

Use this file to discover all available pages before exploring further.

1. Create an account & get your API key

Sign up at app.messages.dev, then go to API Keys in the sidebar and click Create Key. Copy the key. It starts with sk_live_ and is only shown once.
Store your API key somewhere safe. It won’t be displayed again. If you lose it, revoke it from the dashboard and create a new one.

2. Activate your sandbox

Go to the Lines page in your dashboard. You’ll see a sandbox card with a QR code and an activation code. Scan the QR code with your phone (it opens a pre-filled text message) or manually text the code to the sandbox number. Once your message is received, your sandbox is activated and your phone number is paired. You get 50 free messages per day.
The sandbox is a shared iMessage line for testing. For production use, set up a dedicated line.

3. Install the SDK (optional)

npm install @messages-dev/sdk
The SDK is optional. You can use any HTTP client or curl instead. All examples below show both.

4. Send a message

Every message is sent from a line. If you activated the sandbox, use the sandbox line handle and your paired phone number. You can find your line handle on the Lines page in the dashboard.
import { createClient } from "@messages-dev/sdk";

const client = createClient();

await client.sendMessage({
  from: "+15551234567",
  to: "+15559876543",
  text: "Hello from Messages.dev!",
});
That’s it. Your first message is on its way.

5. Receive messages

Local development: use the CLI

The fastest way to receive messages while you’re building is the messages-dev CLI. It streams events from your account and POSTs them at a local URL with the same HMAC headers production webhooks use, so you can develop and test your handler without ngrok, a public URL, or a registered webhook. Install the CLI and authenticate, then:
messages-dev listen --forward-to http://localhost:3000/webhooks
The CLI prints a per-session HMAC secret on first run. Use it as your webhook secret in development, or pin one with MESSAGES_LISTEN_SECRET=….
Prefer the standard webhook path? Expose your local server with ngrok, Cloudflare Tunnel, or any tunnel of your choice and register a real webhook pointing at the public URL. The handler code below is identical either way. See Receive Messages for the full breakdown.
Then handle incoming events on your server exactly as you would in production:
import { verifyWebhook } from "@messages-dev/sdk";

app.post("/webhooks", async (req, res) => {
  const event = await verifyWebhook(
    req.body,
    req.headers["x-webhook-signature"],
    process.env.WEBHOOK_SECRET!,
  );

  if (event.event === "message.received") {
    console.log(`${event.data.sender}: ${event.data.text}`);
  }

  res.sendStatus(200);
});

Production: register a webhook

For production, register a webhook so messages.dev delivers events directly to your public URL. The handler code above is unchanged; only the secret and the source of the deliveries differ. See Webhooks for the full event list, payload shapes, and signature verification details.

6. List your lines (optional)

If you need to look up your line handles programmatically:
await client.listLines();

Next steps

Send Messages

Delivery tracking and error handling

Receive Messages

Webhooks for real-time message delivery

TypeScript SDK

Full SDK reference: pagination, error handling, types

API Reference

All endpoints