---
title: "Errors"
url: "https://coldmeetings.com/docs/errors.md"
canonical_url: "https://coldmeetings.com/docs/errors"
last_updated: "2026-10-20"
type: "reference"
summary: "Every ColdMeetings API error code with its HTTP status, whether it is retryable, what it means in this API and how to fix it."
related: ["https://coldmeetings.com/docs/rate-limits.md", "https://coldmeetings.com/docs/api.md"]
---

# Errors

> **For AI agents:** the complete index of ColdMeetings pages is [llms.txt](https://coldmeetings.com/llms.txt). Every page is also served as markdown at its URL plus .md.

Every ColdMeetings API error code with its HTTP status, whether it is retryable, what it means in this API and how to fix it.

Every error from the API has the same JSON envelope. Branch on `error.code`, which is stable. The `message` is for people and can change.

## The error envelope

```json
{
  "error": {
    "code": "invalid_input",
    "message": "prospects.0.country: Too big: expected string to have exactly 2 characters",
    "fix": "Correct the field named in the message and resend. Each product input schema is in the OpenAPI document. Nothing was charged.",
    "docs_url": "/docs/errors#invalid_input",
    "retryable": false,
    "request_id": "req_Qx7RtVw3ZbN1pEs9fKd2Lm"
  }
}
```

| Field | Meaning |
| --- | --- |
| `code` | A stable identifier, one of the codes below. |
| `message` | What went wrong in this case. |
| `fix` | What to do about it. |
| `docs_url` | A relative path to the entry for this code on this page, such as `/docs/errors#invalid_input`. Open it on this site. |
| `retryable` | `true` when sending the same request again later can succeed. |
| `request_id` | Also sent as the `X-Request-Id` header. Quote it when you contact support. |

## Error codes

| Code | HTTP status | Retryable |
| --- | --- | --- |
| [`unauthorized`](#unauthorized) | 401 | No |
| [`forbidden`](#forbidden) | 403 | No |
| [`insufficient_credits`](#insufficient_credits) | 402 | No |
| [`plan_limit`](#plan_limit) | 402 | No |
| [`subscription_required`](#subscription_required) | 402 | No |
| [`rate_limited`](#rate_limited) | 429 | Yes |
| [`invalid_input`](#invalid_input) | 400 | No |
| [`unknown_product`](#unknown_product) | 404 | No |
| [`method_not_allowed`](#method_not_allowed) | 405 | No |
| [`payload_too_large`](#payload_too_large) | 413 | No |
| [`conflict`](#conflict) | 409 | No |
| [`provider_unavailable`](#provider_unavailable) | 503 | Yes |
| [`internal_error`](#internal_error) | 500 | Yes |

`provider_unavailable` is retryable by default, but the API sets `retryable` to `false` when the service is not configured. Always read the field in the response.

## unauthorized

HTTP 401. Retryable by default: no.

The API key is missing, malformed, revoked or unknown.

What to do: Send a valid key as `Authorization: Bearer cm_live_...`. If the key was revoked, ask the operator for a new one. See [Authentication](https://coldmeetings.com/docs/authentication.md).

## forbidden

HTTP 403. Retryable by default: no.

The key is valid but may not do this. There are two causes: a read only key used on a request that changes data, and a resume of a campaign that ColdMeetings paused itself.

What to do: Use a key with write access for a change. Ask the operator for one if you only have a read-only key. A campaign that ColdMeetings paused itself is resumed only by an operator, after the cooldown. See [Campaigns](https://coldmeetings.com/docs/api/campaigns.md).

## insufficient_credits

HTTP 402. Retryable by default: no.

A prospect import needs more credits than the account has.

What to do: Import fewer prospects, or wait for the next monthly grant. Nothing was imported or charged.

## plan_limit

HTTP 402. Retryable by default: no.

The account is on a paid plan and has reached its limit of sending domains or mailboxes.

What to do: Move to a plan with higher limits. The limits are in [Credits and billing](https://coldmeetings.com/docs/credits-and-billing.md). Nothing was created.

## subscription_required

HTTP 402. Retryable by default: no.

The account has no active plan, and creating a sending domain or a mailbox needs one. Nothing was created.

What to do: Start a checkout for a paid plan, then retry. See [Credits and billing](https://coldmeetings.com/docs/credits-and-billing.md).

## rate_limited

HTTP 429. Retryable by default: yes.

The key made more requests than its bucket allows.

What to do: Wait the number of seconds in the `Retry-After` header, then retry. See [Rate limits](https://coldmeetings.com/docs/rate-limits.md).

## invalid_input

HTTP 400. Retryable by default: no.

The request cannot be accepted as sent: the body is empty, is not JSON or fails validation, or a rule refused it. Rules include a sequence step without `{{unsubscribe}}` or `{{sender_address}}`, a campaign that is not a draft, a domain that is already registered, and a launch with blockers.

What to do: Read the `message`, which names the field or lists the problems, correct the request and resend. Nothing was created or charged.

## unknown_product

HTTP 404. Retryable by default: no.

No endpoint exists at this method and path, or the id you sent does not belong to this account. This code name comes from the shared API platform: in ColdMeetings it means "not found".

What to do: Check the path against the [API reference](https://coldmeetings.com/docs/api.md), and check that the id came from this account.

## method_not_allowed

HTTP 405. Retryable by default: no.

The path exists but not for this HTTP method.

What to do: Use the method shown for that path in the API reference.

## payload_too_large

HTTP 413. Retryable by default: no.

The request body is over 256 KiB.

What to do: Send fewer items. Split a large prospect list into several imports of up to 500.

## conflict

HTTP 409. Retryable by default: no.

The request conflicts with the current state. A checkout is refused when the account already has a subscription, and a campaign resume is refused while the sending engine has not confirmed the pause or the plan's active campaigns are all in use.

What to do: For a checkout, keep the current plan; the operator can change or cancel it. For a resume, wait for the engine to confirm the pause or pause another active campaign, then retry.

## provider_unavailable

HTTP 503. Retryable by default: yes.

A step needs an outside service and it is not available. When `retryable` is `false`, the service is not configured on this server. When it is `true`, it failed for now.

What to do: If `retryable` is `true`, retry later with exponential backoff. If it is `false`, retrying will not help until the operator configures the service. Nothing is simulated and nothing was charged.

## internal_error

HTTP 500. Retryable by default: yes.

An unexpected error on our side.

What to do: Retry once after a short wait. If it fails again, email [hello@coldmeetings.com](mailto:hello@coldmeetings.com) with the `request_id`.

## Related

- [Rate limits](https://coldmeetings.com/docs/rate-limits.md)
- [API reference](https://coldmeetings.com/docs/api.md)
