---
title: Error codes
description: Coinetic API error codes: what each one means and how to fix it, covering signatures, idempotency, invoices, assets, refunds and rate limits.
url: https://coinetic.money/docs/errors/
lang: en
---

# Error codes

Error bodies always have the same shape. Rely on `code`, not the message: the message is written for humans and may change.

```json
{ "error": { "code": "duplicate_order", "message": "An invoice for this order_id already exists" } }
```

> **When it's safe to retry.** On `429`, `500`, `503`, `idempotency_in_progress` and network errors, **using the same `Idempotency-Key`**: no duplicates will be created.

## Request and access

| HTTP | code | Cause and fix |
| --- | --- | --- |
| 400 | `bad_json`, `bad_body` | Body isn't JSON, has unknown fields, or sends an amount as a number instead of a string: fix the request |
| 400 | `bad_idempotency_key` | Key missing or malformed: 8–128 printable ASCII characters, not starting with `d:` |
| 400 | `bad_query` | Invalid list parameters |
| 401 | `unauthorized` | Signature, timestamp, nonce or key problem: see [CP-HMAC](https://coinetic.money/docs/authentication/) |
| 403 | `merchant_suspended` | Merchant suspended: contact support |
| 403 | `merchant_not_approved` | Onboarding incomplete or application under review: finish the setup wizard in the dashboard |
| 403 | `billing_suspended` | A fee invoice is unpaid: pay it in the dashboard under “Billing,” and the suspension lifts immediately |
| 404 | `not_found` | The invoice doesn't exist or belongs to someone else |
| 413 | `body_too_large` | Body exceeds the limit: trim `metadata` |
| 429 | `rate_limited` | Too many requests: retry with exponential backoff |
| 500 | `internal` | Internal error: retry with the same `Idempotency-Key` |

## Invoices and idempotency

| HTTP | code | Cause and fix |
| --- | --- | --- |
| 409 | `duplicate_order` | `order_id` already used: pick a new one, such as `ORDER-1001-2` |
| 409 | `idempotency_conflict` | Same key with a different body |
| 409 | `idempotency_in_progress` | The first request is still running: retry in 1–2 s |
| 409 | `invoice_not_payable` | Invoice expired or closed: create a new one |
| 422 | `invalid_order_id`, `invalid_price_amount`, `invalid_price_currency`, `invalid_return_url`, `invalid_expires_in_seconds`, `invalid_metadata` | A field failed validation: the message explains the rule |
| 422 | `invalid_allowed_assets` | None of the listed assets is available: the message gives the reason for each |
| 422 | `no_assets` | No assets are available at all: check your wallets and assets in the dashboard |
| 422 | `amount_too_small` | The amount is below the minimum for every available asset |

## Currency selection on the checkout page

The checkout page handles these errors. Your server only sees them if you call `select` yourself.

| HTTP | code | Cause |
| --- | --- | --- |
| 409 | `asset_locked` | Currency change attempted after a payment |
| 409 | `wallet_not_configured` | No active receiving wallet on this network |
| 409 | `wallet_changed`, `address_conflict` | Retry the selection |
| 422 | `asset_not_allowed` | The asset isn't on the invoice or is no longer allowed |
| 503 | `rate_unavailable` | No confirmed rate available: offer a stablecoin |
| 503 | `network_unavailable` | Payments on this network are temporarily unavailable: choose another |

## Refunds

| HTTP | code | Cause |
| --- | --- | --- |
| 403 | `merchant_inactive` | Store suspended or key revoked |
| 409 | `invoice_not_paid` | No asset selected on the invoice, so there's nothing to refund |
| 409 | `nothing_to_refund` | Everything has already been refunded or requested |
| 409 | `too_many_refunds` | 20 open requests on this invoice |
| 409 | `refund_executor` | The platform executes this refund, not you |
| 409 | `invoice_status_changed` | The invoice status changed after the request: retry with `"ack_status_change": true` |
| 422 | `amount_exceeds_refundable` | Amount exceeds what's refundable: lower it or use `"full"` |
| 422 | `invalid_amount`, `invalid_address`, `invalid_tx_hash` | A field failed validation |
