One API, every channel

You post one message object. The gateway picks the channel that handset can render, keeps the same id through every receipt, and names the reason if it never lands.

api.messagereach.net/v1
Base URL
5
SDKs
OpenAPI 3.1
Spec
A hexagonal gateway core module with glowing seams and connector arms reaching to floating cubes

Authentication

Keys are scoped to an environment and to a set of route classes. Send the key as a bearer token on every request. There is no session, no refresh and no cookie.

request headers

Authorization: Bearer mr_live_7c41...
Content-Type: application/json
Idempotency-Key: spins-88431
MessageReach-Version: 2026-05-01

Conventions

Four rules cover every resource, so once you have written one call you have written all of them.

IdempotencyRetry a write within 24 hours under the same Idempotency-Key and it sends once.
PaginationLists are paged by cursor. A null next_cursor means the last page.
VersioningEach key sits on a dated version. The version header overrides it per call.
TimesEvery timestamp is RFC 3339 in UTC with the offset spelled out.

Send one message

Five SDKs and a plain HTTP surface. Pick whichever you already have in the codebase.

Send a message
$mr = new MessageReach($_ENV['MR_KEY']);

$msg = $mr->messages->send([
  'sender'   => 'LUXPLAY',
  'to'       => '+35799xxxxxx',
  'template' => 'free_spins_v4',
  'channel'  => 'sms',
  'vars'     => ['spins' => 50, 'expires' => '00:00'],
]);

echo $msg->id;      // msg_01K4TQ8V
echo $msg->state;   // queued

What comes back

{
  "id": "msg_01K4TQ8V",
  "state": "queued",
  "channel": "sms",
  "route": "CY-direct-02",
  "segments": 1,
  "eta_ms": 180
}

That is an acknowledgement that the gateway took the message, not proof of delivery. Subscribe to events, or poll the resource while you are still learning the shape.

Five SDKsPHP, Node, Python, Go and Java, each tracking the live release and installed the way that language expects.
Scoped keysPer environment and per route class, so a marketing key cannot send transactional traffic or the reverse.
OpenAPI 3.1A complete machine-readable spec on every version bump, ready to scaffold a client in whatever your team writes.

Messages

POST/v1/messagesSendOne number or a whole list, a template or your own text, channel chosen per handset. Repeats deduplicated for 24 hours.
GET/v1/messages/{id}RetrieveWhere it stands now, each step it moved through, and what the network said if it stopped.
GET/v1/messagesListPaged by cursor. Narrow by sender, market, template, delivery state or when it was queued.
DELETE/v1/messages/{id}CancelWorks while it is still queued. Once the carrier has it, the answer is 409.

Senders and routes

POST/v1/sendersRegister a senderFile the sender name the player will see in the thread, plus the paperwork that market wants.
GET/v1/senders/{id}Registration statusPer-network status for the market, and what is outstanding if a submission has stalled.
GET/v1/routesAvailable routesWhat each bind on your key reaches, how quick it is, its traffic class and the rate.

Conversations

GET/v1/conversations/{ref}Read a threadEvery message in and out for one player reference, in order, with delivery state.
POST/v1/repliesReply in threadAnswer an inbound message, threaded to the parent, on whichever channel it arrived.

Events and usage

POST/v1/webhooksSubscribePick which classes you want pushed. The secret is shown once and never again.
GET/v1/eventsReplayReach back thirty days for whatever you missed, narrowed by class or position.
GET/v1/usageUsage and spendHow much went out and what it cost, split by market, channel and class, over any dates.

Error codes

Errors carry a stable machine name alongside the status, so you can branch on the name rather than parsing a message that might be reworded.

401invalid_keyNo such key, or it was withdrawn, or it belongs to another environment.
409market_not_licensedThat number sits in a country this key is not cleared for. Enable it under licences.
409sender_unregisteredThat sender name has no approval yet on the network carrying this number.
422no_consentThis player never agreed to hear from you, or their last action was to leave.
429rate_exceededSending faster than this key allows. Retry-After gives the seconds to wait.
503route_unavailableNo healthy route into that market right now. Send again; the key still stops duplicates.

error body

{
  "error": {
    "name": "market_not_licensed",
    "status": 409,
    "message": "This key does not cover the DE market.",
    "docs": "https://messagereach.net/our-api#errors"
  }
}

Guides for the parts that are not obvious from the reference: the first campaign, what a receipt actually means, and the sender rules per market.

Read the guides

Try it against the sandbox

A free key runs the whole reference against simulated handsets and networks, down to the rejections you need to see fire before go-live.