# Send a message

> One endpoint sends everything. Beam picks the best channel per contact, paces the send, and delivers.

POST https://beam.aisync.link/v1/messages

  
| Field | Type | Description | 
  
| to | string, required | The recipient's phone number. | 
  
| message | string, required | What to say. Plain text; sent exactly as written. | 
  
| first_name | string, optional | Saved to the contact the first time you message them. | 
  
| attachments | string[], optional | Public HTTPS file links. Up to 10 on blue bubbles, 3 on texts. See Photos & attachments. | 
  
| effect | string, optional | Full-screen effect on blue bubbles: confetti, lasers, balloons, fireworks, celebration, love, slam, loud, gentle, spotlight, echo, invisible_ink, shooting_star. Ignored on texts. | 

curlJavaScriptPythonCopy
```
curl -X POST https://beam.aisync.link/v1/messages \
  -H "x-api-key: YOUR_WORKSPACE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "+15551234567",
    "message": "Hey Sarah, you are booked for Tuesday at 2. See you then!",
    "effect": "confetti"
  }'
```

```
const res = await fetch("https://beam.aisync.link/v1/messages", {
  method: "POST",
  headers: {
    "x-api-key": process.env.BEAM_KEY,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    to: "+15551234567",
    message: "Hey Sarah, you are booked for Tuesday at 2. See you then!",
    effect: "confetti",
  }),
});
const data = await res.json();
// { id: "41", status: "queued", to: "+15551234567" }
```

```
import os, requests

res = requests.post(
    "https://beam.aisync.link/v1/messages",
    headers={"x-api-key": os.environ["BEAM_KEY"]},
    json={
        "to": "+15551234567",
        "message": "Hey Sarah, you are booked for Tuesday at 2. See you then!",
        "effect": "confetti",
    },
)
print(res.json())  # { "id": "41", "status": "queued", "to": "+15551234567" }
```

### Response

200 OKCopy
```
{
  "id": "41",
  "status": "queued",
  "to": "+15551234567"
}
```

Queued means protected, not slowBeam sends from a live queue that paces every number: warm-up limits, business hours, human-like spacing. Most messages go out within minutes. If the recipient has opted out you get a 403 and nothing sends.

## How the channel is chosen

Beam checks whether the recipient supports blue bubbles. If yes, the message goes as iMessage, with automatic text fallback if a blue-bubble delivery fails mid-flight. If not, it goes as a text. Either way it comes from the contact's pinned number, so their whole conversation lives in one thread.
