Concepts
Authentication and keys
How API keys work, what their abilities allow, how to limit a key, and what each failure means.
Send the key as a bearer token#
curl -sS "$MYCOMM_URL/v1/account" -H "Authorization: Bearer mc_live_..."
Create keys in the portal (Developers, API keys) or with POST /v1/api-keys. The token is shown once, when the key is
created; MyComm stores only a keyed hash of it, so a lost key is replaced, not recovered. Keep keys on your server. The API
sends no CORS headers, because a key in a browser is a leaked key; to let a browser pair a phone, use
hosted connect, which needs no key in the page.
Key formats#
| Kind | Starts with | Length | Used on |
|---|---|---|---|
| Account key | mc_live_ |
54 characters | /v1, for one account |
| Partner key | mc_partner_ |
57 characters | /partner/v1, and /v1 with the MyComm-Line header |
The last six characters of a key are a checksum, so a mistyped or truncated key is refused immediately with
401 UNAUTHENTICATED and details.reason: "malformed_key", before anything is looked up. Secret scanners can recognise the
prefix too. A key that is well formed but unknown, revoked or expired also answers 401, with no reason, so nobody can learn
whether a key ever existed.
Abilities#
Every endpoint names the one ability it needs in the API reference. A key without it gets
403 ABILITY_MISSING with details.required.
| Ability | Lets the key |
|---|---|
messages:send |
Send, batch, cancel, retry and dry-run messages |
messages:read |
Read and search messages and their events |
conversations:read |
Read conversations and their messages |
conversations:write |
Mark read, archive, delete and reply in conversations; block from a conversation |
contacts:read / contacts:write |
Read; create, update, merge, delete and import contacts and custom fields |
groups:write |
Create groups and smart lists, change their members |
templates:read / templates:write |
Read and render; create, update and archive templates |
campaigns:read / campaigns:write |
Read campaigns and reports; create, start, pause and cancel |
automation:read / automation:write |
Read and test automation rules; change them |
channels:read / channels:write |
Read channels, lines and devices; pair phones, change rate policies, create lines |
webhooks:write |
Manage webhook endpoints and deliveries |
reports:read |
Statistics and message exports |
suppressions:read / suppressions:write |
Read the opt-out list and check addresses; add and remove opt-outs |
media:write |
Upload media |
account:write |
Change account settings |
keys:write |
List, create and revoke API keys |
A key created without a list of abilities gets every ability except keys:write and account:write; a key limited to
lines gets a smaller default set (send, read, reply, read contacts and templates, media, webhooks). Give each integration
only what it uses: a service that only sends needs messages:send, and a reporting job needs messages:read or reports:read.
Limit a key#
When you create a key you can limit it:
| Option | Effect |
|---|---|
line_ids |
The key sees and sends from these lines only. Anything else answers 404 NOT_FOUND, never 403, so ids cannot be probed. |
channel_types |
The same, by kind of channel, including lines created later. |
allowed_ips |
Requests from other addresses are refused. IPv4, IPv6 and CIDR ranges. |
expires_at |
The key stops working at that time. |
A key limited to lines cannot hold the abilities that change the whole account (groups:write, templates:write,
campaigns:*, automation:write, channels:write, suppressions:write, account:write, keys:write).
Partner keys#
A partner key manages its lines through /partner/v1. To send and read through one of them on /v1, add the header
MyComm-Line: <line id>:
| Header | Answer |
|---|---|
| Missing | 400 LINE_CONTEXT_REQUIRED |
| Not a UUID | 400 INVALID_HEADER |
| A line that is not yours, or was detached | 403 LINE_CONTEXT_INVALID (the same answer for every case) |
A partner key reaches only the message and conversation endpoints of that line and GET /v1/lines/{id}; any other /v1
endpoint answers 403 PARTNER_ROUTE_NOT_ALLOWED. An account key never sends the header (400 INVALID_HEADER). See
Partners.
Rotate a key#
- Call
POST /v1/api-keys/{id}/rotate. It returns a new key with the same name, abilities and limits, and its token once. The old key keeps working forgrace_period_hours(default 24, at most 168) and then stops. - Deploy the new token to your server within that time.
last_used_atandlast_used_ipon the old key show whether anything still uses it. - To end the old key sooner, revoke it (
DELETE /v1/api-keys/{id}), or rotate withgrace_period_hours: 0, which revokes it at once.
curl -X POST https://mycomm.cogneer.tech/v1/api-keys/KEY_ID/rotate -H "Authorization: Bearer $MYCOMM_API_KEY" -H "Content-Type: application/json" -d '{"grace_period_hours": 24}'
The calling key needs keys:write and must hold every ability of the key it rotates. A revoked or expired key cannot be rotated
(409 INVALID_STATE); create a new one.
Rotate when someone who knew a key leaves, and at once if a key may have leaked.
Trace a request#
Every response carries MyComm-Request-Id; an error carries the same value in error.request_id. Log it with each call and
quote it to support.
What the failures mean#
| Status | Code | Meaning |
|---|---|---|
| 401 | UNAUTHENTICATED |
No usable key: absent, malformed, unknown, revoked or expired |
| 403 | ABILITY_MISSING |
The key is fine but lacks the ability in details.required |
| 403 | WRONG_KEY_KIND |
An account key on /partner/v1, or the reverse |
| 403 | ACCOUNT_SUSPENDED |
The account is suspended; only GET /v1/account works |
| 429 | RATE_LIMITED |
Too many requests, or too many failed authentications from one address; wait Retry-After seconds |
The full list is in the error reference.