MyComm docs
Menu

Start

Quickstart: send a message

From an API key to a delivered message, with the request and the answer for every step.

Set two shell variables once; the commands below use them.

export MYCOMM_URL=https://mycomm.cogneer.tech
export MYCOMM_API_KEY=mc_live_...   # shown once when you create the key

1. Create a key and connect a phone#

In the portal, open Developers, API keys, and create a key. Give a development key the abilities it needs and nothing more: messages:send and messages:read to send and look at messages, channels:read to list what you can send from. The token is shown once; keep it in your secret store. Connect a phone from the portal, or from your own page with hosted connect.

2. Check the key#

curl -sS "$MYCOMM_URL/v1/account" -H "Authorization: Bearer $MYCOMM_API_KEY"

A 200 with your account means the key works. A 401 UNAUTHENTICATED has a details.reason of missing_key or malformed_key when the header is absent or the key cannot be one (the last six characters are a checksum).

3. Find what you can send from#

GET /v1/channels lists the connected numbers; GET /v1/lines lists the lines you send from, each with its senders.

curl -sS "$MYCOMM_URL/v1/lines" -H "Authorization: Bearer $MYCOMM_API_KEY"

Copy the id of the line you want. For your app, create a key limited to that line (line_ids: [id]): it sends without naming a sender, the line picks a healthy SIM, and the key sees nothing of the account's other lines. A key that can use several lines names the line with line_id, as below.

4. Send with an idempotency key#

curl -sS -X POST "$MYCOMM_URL/v1/messages" \
  -H "Authorization: Bearer $MYCOMM_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1094-ready-1" \
  -d '{
    "line_id": "LINE_ID",
    "to": "+923001234567",
    "body": "Your order #1094 is ready for pickup.",
    "category": "transactional",
    "reference_id": "order-1094"
  }'

The answer is 202 Accepted with the message and a warnings list (empty when there is nothing to tell you):

{
  "id": "0198f3a2-7c41-7e0b-9d52-6a1f3b8c4e10",
  "direction": "outbound",
  "type": "sms",
  "to": "+923001234567",
  "body": "Your order #1094 is ready for pickup.",
  "status": "queued",
  "hold_reason": null,
  "reference_id": "order-1094",
  "created_at": "2026-10-01T09:15:02Z",
  "warnings": []
}

The message resource has more fields than shown; the reference lists them all. Store the id and your Idempotency-Key with your own record. Repeating the request with the same key within 24 hours returns the same answer with Idempotent-Replayed: true instead of sending twice; the idempotency page has the rules.

queued does not mean sent. A message can wait with a hold_reason (the phone is offline, quiet hours, a safety limit); see the message lifecycle.

If the answer is a 422, read error.message and error.details: VALIDATION_FAILED lists each broken field with the rules it broke, and the other codes say what the rule was. Every error links to its entry in the error reference through error.doc_url.

5. Follow the message#

curl -sS "$MYCOMM_URL/v1/messages?reference_id=order-1094" -H "Authorization: Bearer $MYCOMM_API_KEY"

The status moves from queued to leased (a phone has it), sent and delivered, or ends as failed, expired or cancelled. Polling is fine while you build; in production subscribe to the message.* events with a webhook and keep polling only as a recovery path. Use backoff and stop at your own timeout.