What you are actually calling
Every /v1/* request carries the workspace key in the x-api-key header. Keep it server-side. Responses are JSON. Errors are a plain sentence in an error field. Phone numbers can be 10-digit, 11-digit, or international. Beam normalizes them.
The OpenAPI file lists 20 paths. Messaging, presence, numbers, the CRM opt-in webhook, and email are all in that file. The intro in the docs is the short map. The file is the contract.
Open the OpenAPI contract or the API introduction.
Send a message
POST /v1/messages takes to and message. Optional fields include first_name, public HTTPS attachments, and a full-screen effect that applies on blue bubbles only. Effects are ignored on texts. You get back an id and status: "queued".
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":"Thursday at 10:00 or 2:30. Which works better?"}' Never assume delivery from a 200. The send is queued. Beam paces it for the number: warm-up limits, the sending window, and irregular spacing. Most messages go out within minutes inside that window. If the recipient has opted out, the send returns 403 and nothing goes out. Poll GET /v1/messages/:id until the status is delivered or failed, or subscribe to webhooks. Do not poll in a tight loop. sent is not delivered.
Beam checks whether the phone supports blue bubbles and picks the channel. It does not force iMessage, and it does not guarantee RCS. You can cancel a message that is still queued with DELETE /v1/messages/:id.
Check a number before you spend a send
GET /v1/availability/:phone is the single-number blue-bubble check. For a list, screening accepts up to 25,000 numbers per check and reuses recent results for 24 hours. Screening does not deliver a message and does not notify the person.
Treat "could not check" as unfinished, not as proof the phone is text-only. The same rule belongs in a campaign: do not burn a day of ramp on numbers you have not screened. Daily pacing is a separate question. Read the sending limits before you size a list.
Typing, read receipts, and tapbacks
Three endpoints carry the signals a person expects on a blue thread:
POST /v1/typingshows the typing indicator.POST /v1/readsends a read receipt.POST /v1/reactionslands a tapback: love, like, dislike, laugh, emphasize, or question.
These are part of the iMessage channel. SMS does not support them, so Beam only offers them on blue-bubble threads. Read status is shown only when the channel supplies a real read event. Beam does not invent an open rate for texts.
Signed events
In Settings, paste an HTTPS endpoint. Beam shows a signing secret once. Each event is a POST with a JSON body and a Beam-Signature header. Respond with any 2xx quickly and process the work after.
| Event | When it fires |
|---|---|
message.received | A contact texted you |
message.sent | An outbound went out |
message.failed | An outbound could not be delivered |
contact.opted_out | A contact opted out |
assistant.booked | The assistant booked a call, with an appointment id |
assistant.handoff | The assistant needs a person |
The signature scheme is HMAC-SHA256 over t + . + the raw body, using your signing secret. The header looks like t=<unix_seconds>,v1=<hex>. Reject events older than 5 minutes. Compare in constant time. In this version, events are pushed once with a 5 second timeout and no automatic retries. If you cannot afford to miss one, reconcile with conversation history on a schedule.
The signing write-up is in the webhook signing guide.
Email uses the same key
Beam also sends and receives email. /v1/email/* covers the plan state, domains, domain verification, mailboxes, threads, messages, and human takeover. The key resolves the workspace on the server. There is no tenant id in the body, and no way to ask for another workspace.
A 202 on an email send means queued, not delivered. Use the thread timeline and signed events for the final state. Do not automatically retry a result you are not sure about. Email live-send starts off: honor draft-only mode, stop on human takeover, and only send from a mailbox the workspace endpoint returned. The GoHighLevel email bridge is still behind a feature flag.
GoHighLevel is a webhook, not a second API
Workflow sends do not go through POST /v1/messages with a pasted phone number. A Custom Webhook step posts to /api/crm/workflows/send with a workspace bearer token, and Beam reads the number from the GoHighLevel contact. New opted-in leads can also hit POST /t/:workspace/optin. GHL's own Send SMS action does not select the Beam channel. A Marketplace action named Send with Beam is not confirmed published.
How the GoHighLevel connection works.
What this API will not do for you
- It will not send from a personal Apple ID. Lines are dedicated business numbers.
- It will not turn a cold list into unlimited volume. Pacing counts new outbound-first conversations. See the planning range.
- It will not mark a booking until the calendar confirms it.
- It will not retry a webhook you missed.
- It will not show a price on this page. See plans in the app.
FAQ
Does Apple have an official iMessage API?
Apple does not publish a public API for sending iMessage from your own backend. Apple Messages for Business is a different, registered, inbound-first channel. Beam is not that product, and Beam does not claim Apple registration, partnership, or endorsement.
How do I send an iMessage programmatically?
POST https://beam.aisync.link/v1/messages with your workspace key in the x-api-key header and a JSON body containing to and message. Keep the key on the server. A successful response means the send is queued, not that it was delivered.
How do I check whether a phone can receive iMessage before I send?
GET /v1/availability/:phone checks one number. Screening can check a list of up to 25,000 numbers. Recent results are reused for 24 hours. A result of could not check is its own state. Do not treat it as text-only. Screening does not send a message.
Can I send read receipts, typing indicators, and tapbacks through the API?
Yes, on blue-bubble threads. The endpoints are POST /v1/typing, POST /v1/read, and POST /v1/reactions. Tapbacks are love, like, dislike, laugh, emphasize, and question. SMS does not support these signals, so Beam only offers them on blue threads.
What does an iMessage API cost?
This site does not publish prices. Capacity is lines and paced new conversations, not an unlimited message meter. Plans are shown in the Beam app.