Skip to content

Errors

When a request fails, the API answers with an HTTP status of 400 or above and a JSON body that says what went wrong.

{
"error": {
"type": "invalid_request",
"code": "invalid_parameter",
"message": "...",
"param": "options[1].asset",
"doc_url": "https://docs.ctpeway.com/errors#invalid_parameter",
"request_id": "req_..."
}
}
Field Meaning
type The kind of error. One of the eight types below. Decide how to react from this.
code A stable, specific code, such as invoice_not_found. Use it when you need to tell two errors of the same type apart. All codes are listed below.
message An explanation for a person. Its wording can change, so never make your code depend on it.
param The request field the error is about, when there is one.
doc_url A link to this page, to the entry for the code.
request_id The id of the request, also sent in the Request-Id response header. Quote it when you contact support.
Type Status Meaning What to do
invalid_request 400 Something in the request is missing or wrong. param names the field. Fix the request. Sending it again unchanged will fail again.
authentication 401 The API key is missing, wrong, revoked or expired. Check the key and the Authorization header.
permission 403 The key is valid but may not do this. Give the key the permission it needs, or use another key.
not_found 404 The object does not exist, or it belongs to the other mode. Check the id, and whether you are using a test key or a live key.
conflict 409 The object is not in a state that allows this action. Retrieve the object and look at its status.
idempotency 422 The idempotency key was already used with a different request. Use a new key for a new operation.
rate_limited 429 Too many requests. Wait, then try again.
api_error 500 Something went wrong at cTpeWay. Try again later, with the same idempotency key.
  • Branch on type, and on code when you need more detail. Never on message.
  • Do not retry what cannot succeed. invalid_request, authentication, permission, not_found and conflict will give the same answer until you change something.
  • Retry rate_limited and api_error, waiting longer after each failure.
  • Retry safely. When you repeat a POST, send the same idempotency key, so that an operation that did succeed the first time is not done twice.
  • Log request_id.

The Node SDK turns each type into its own error class and does the safe retries for you. See Node SDK.

Every error has a code. The API links each error to its entry on this page (doc_url), and each endpoint in the API reference lists the codes it can answer with.

The two lists below are generated from the API description, so they are complete. A few codes have a longer explanation under More about some codes. For the others, the message of the response says what went wrong.

Each code is followed by the endpoints that can return it.

Type invalid_request. A field of the request failed validation. param says which one, using a path such as options[1].asset for a field inside a list.

Type permission. The API key does not have the permission this endpoint needs. See Permissions.

Status 403. The request was made with a publishable key (ctp_…_pk_…). A publishable key can only list networks, list assets and get a rate. Use a secret key, from your server. See Key types.

The account is blocked. Its API keys do not work, and nobody can sign in to the dashboard.

The account is on hold. Payouts and refunds cannot be created while it is.

The API key is limited neither by an IP allowlist nor by a payout allowlist. A key that pays out, or refunds, needs at least one: with an IP allowlist it pays any valid address, only in requests from those IP addresses; with a payout allowlist it pays only the addresses on it. Set them under API keys in the dashboard. The same code refuses creating such a key, or a change that would leave a key with neither. See Payouts and refunds need more.

The destination address is not on the payout allowlist of the API key. Add it to the allowlist, or use a key that has it. A key with a payout allowlist is held to it even when it also has an IP allowlist.

Status 503. cTpeWay has paused payouts and refunds for the moment, for instance during maintenance. Nothing was created. Try again later with the same Idempotency-Key; the dashboard shows a notice while the pause lasts.

A payout you created before the pause waits and is sent when payouts resume. If it is not sent within two hours of being created, it fails with failure_code: stale and nothing is sent; create it again with a new idempotency key.

The endpoint needs an Idempotency-Key header and the request had none. Payouts and refunds require one, because they move money. See Idempotency.

Type idempotency. The Idempotency-Key of this request was used before, with a different request. An idempotency key belongs to one operation. See Idempotency.

Status 403. The Idempotency-Key was first used by another API key. A stored answer is given only to the key that made the request, or to a key that has all of that key’s permissions. See Idempotency.

Status 409. An earlier request with the same Idempotency-Key is still being processed. Wait for the time given in the Retry-After header and send the request again with the same key.

The endpoint exists in test mode only, and the request was made with a live key. The payment simulators and the test webhook ping are test-mode endpoints. See Testing.

Status 503. cTpeWay has no fresh market price for the asset at the moment, so it cannot quote a rate. Try again shortly.