MyComm docs
Menu

Errors

Errors and limits

Every error response has the same shape:

{
  "error": {
    "code": "RECIPIENT_OPTED_OUT",
    "message": "The recipient +923001234567 opted out of marketing messages. Send it as transactional or remove the opt-out.",
    "details": {"address": "+923001234567", "suppressed_at": "2026-10-20T09:14:00Z"},
    "request_id": "01923f80-5c6a-7b10-9c21-0d3e4f5a6b7c",
    "doc_url": "https://mycomm.cogneer.tech/docs/errors#recipient-opted-out"
  }
}
  • code is stable. Branch on it. New codes can appear, so keep a fallback on the HTTP status.
  • message is for people. It says what happened and what to do, and its wording can change. Never parse it.
  • details holds the facts the code needs, with the same keys every time. The keys of each code are listed in the error reference.
  • request_id is also in the MyComm-Request-Id response header. Quote it when you ask for help.
  • doc_url opens the code's entry in the error reference.

What each status means#

Status Meaning What to do
400 The request cannot be read (MALFORMED_REQUEST) or a header is wrong (INVALID_HEADER, with details.header) Fix the request; do not retry unchanged
401 No usable key (UNAUTHENTICATED; details.reason is missing_key or malformed_key when the key is absent or has a typo) Send Authorization: Bearer <key> with a complete key
403 The key is fine but may not do this (ability, IP list, account state) Use a key that may, or fix the account state
404 The resource does not exist, belongs to another account or is outside the key's scope Check the id
409 A conflict with current state: a repeated reference_id, a reused Idempotency-Key, a name already taken Read the code; often the first request already worked
413 The body is too large (JSON over 1 MB, uploads over 21 MB; details.max_bytes) Send less per request
415 The Content-Type is missing or wrong (details.expected) Send Content-Type: application/json (multipart/form-data on the two upload endpoints)
422 The request is well-formed but cannot be accepted: invalid fields, an opt-out, a closed channel Read the code and details; do not retry unchanged
429 Too many requests Wait Retry-After seconds, then retry
5xx The server failed or is in maintenance Retry with backoff and the same Idempotency-Key

An empty POST body counts as {}: actions such as pause, unarchive, cancel and replay need no body.

Line errors#

Code When
LINE_REQUIRED A send names no line, channel or address, and the key is not limited to exactly one line
CHANNEL_LINE_MISMATCH The sender fields point at different lines, or the channel is not a sender of the line
LINE_HAS_NO_SENDERS The line has no enabled sender
LINE_ARCHIVED The line is archived; unarchive it or send from another
LINE_IS_DIRECT The Direct line cannot be archived

All are 422. Sending to one of your own numbers is allowed.

Invalid fields#

422 VALIDATION_FAILED lists every broken field in details.fields. A field lists every rule it broke, each with a code:

{"error": {"code": "VALIDATION_FAILED", "message": "The request has invalid fields. See details.fields for each field and the rule it broke.",
  "details": {"fields": {
    "to": [{"code": "REQUIRED_WITH", "message": "Send to (a phone number) or contact_id."}],
    "body": [{"code": "REQUIRED_WITH", "message": "Send a body, media_ids, template_id or content: the message has nothing to say."}],
    "expires_in": [{"code": "OUT_OF_RANGE", "message": "expires_in must be at least 60 seconds."}]}},
  "request_id": "01923f80-5c6a-7b10-9c21-0d3e4f5a6b7d", "doc_url": "https://mycomm.cogneer.tech/docs/errors#validation-failed"}}

The field codes are REQUIRED, REQUIRED_WITH, REQUIRED_WHEN, EXCLUSIVE, INVALID_TYPE, INVALID_FORMAT, INVALID_ENUM, INVALID_NUMBER, OUT_OF_RANGE, TOO_LONG, TOO_SHORT, NOT_FOUND, NOT_UNIQUE and INVALID. Fields the API does not know are ignored, so a typo in an optional field is not reported: check names against the API reference.

Idempotency and retries#

Send an Idempotency-Key (1 to 255 printable ASCII characters; a UUID is best) on every POST you may retry. The first answer, success or 4xx, is kept for 24 hours and returned again with Idempotent-Replayed: true. A 5xx is not kept, so a retry runs again. The same key with a different body answers 409 IDEMPOTENCY_KEY_REUSED; while the first request still runs, 409 IDEMPOTENCY_IN_PROGRESS. A bad key answers 400 INVALID_HEADER, also on a dry_run.

Limits#

  • Request rate: 600 requests a minute per account key (partner keys: 600 a minute per client account and 3,000 overall; /partner/v1: 300). Every response carries RateLimit-Limit, RateLimit-Remaining and RateLimit-Reset; a 429 adds Retry-After.
  • Wrong keys: 60 failed authentications a minute per IP address, then 429 until the minute ends. A correct key is never counted.
  • Body size: JSON up to 1 MB, uploads up to 21 MB.
  • Lists: limit 1 to 200 (default 50) with an opaque cursor; a cursor older than 24 hours or used with other filters answers 400 INVALID_CURSOR.
  • IP allow-lists: a key with allowed_ips answers 403 IP_NOT_ALLOWED from any other address.

Sending speed is not an API limit. MyComm holds messages to protect each SIM; see keeping your SIM safe.