The API uses conventional HTTP status codes. A 2xx means success; a 4xx means the request was rejected (usually something you can fix); a 5xx means a problem on Etherfuse’s side.
Error responses carry a short, human-readable message describing the problem — for example, An order with this transaction ID already exists. Depending on the endpoint, the body is either plain text or a JSON object { "error": "<message>" }. Switch on the HTTP status code as the primary signal and treat the message as human-facing detail — there is no stable machine-readable error code to parse.
Status codes
| Code | Meaning | Typical cause |
|---|
400 | Bad Request | Invalid or missing fields, or a missing/expired quote. |
401 | Unauthorized | Missing/invalid API key, or a Bearer prefix on the header. See Authentication. |
403 | Forbidden | Your organization isn’t authorized to access this resource. |
404 | Not Found | A referenced ID doesn’t exist or isn’t linked to the customer/org (wrong customerId, bankAccountId, publicKey, etc.). |
409 | Conflict | The resource already exists, or it collides with a business rule. See Idempotency. |
422 | Unprocessable Entity | The request is well-formed but can’t be processed — e.g. an unsupported asset, currency, or blockchain for the requested operation. |
424 | Failed Dependency | A valid quote couldn’t be produced for the requested trading path right now (a FailedToGetQuote). Transient — retry with backoff. |
500 | Internal Server Error | Unexpected error on our side. Safe to retry with backoff. |
501 | Not Implemented | The requested capability isn’t available for this route (e.g. an unsupported provider or flow). |
503 | Service Unavailable | A dependency is temporarily down. Retry with backoff. |
Common errors
| Message / situation | Code | Cause | Fix |
|---|
Proxy account not found | 404 | customerId or publicKey doesn’t match onboarding | Use the exact IDs from the onboarding call. |
Bank account not found | 404 | bankAccountId is wrong or belongs to a different customer | Verify the bank account is linked to this customer. |
| Quote expired | 400 | Order created more than 2 minutes after the quote | Create a fresh quote and retry. |
An order with this transaction ID already exists | 409 | Re-used an orderId | See Idempotency — treat as already-created. |
A pending onramp order already exists for this bank account and amount | 409 | Duplicate pending onramp for the same (bank account, amount) | Wait for the existing order to settle, or change the amount. |
401 Unauthorized | 401 | Bearer prefix or wrong-environment key | Send the raw key matching the base URL. |
FailedToGetQuote — “Temporarily unable to get a valid quote for this trading path” | 424 | Etherfuse can’t currently guarantee the fee/spread for that trading path | Transient protection — retry with exponential backoff. |
OrderTooSmall — “Combined fee … exceeds maximum (5000 bps / 50%)“ | 400 | Amount too small to cover fees (EVM offramp gas, or a new-wallet Stellar onboarding cost) — the fee can’t exceed 50% of the order | Increase the amount (on EVM, offramp ≳ 50 CETES). See Base. |
tx_too_late (returned by Stellar on submit) | — | The pre-built Stellar transaction expired (~1–2 min TTL) before you submitted it | Regenerate with regenerate_tx and resubmit promptly. See Stellar. |
IDs are permanently bound after onboarding. The customerId, bankAccountId, and publicKey are linked during onboarding and cannot be mixed across customers — mismatches surface as 404.
Handling errors
4xx — fix the request before retrying. Retrying an identical bad request will fail the same way. For 409 on a create, treat the resource as already created (see Idempotency).
424 — a quote couldn’t be produced for that trading path right now (a price/spread couldn’t be guaranteed). It’s transient — retry with exponential backoff.
5xx — 500 and 503 are transient; retry with exponential backoff. Because creates use client-generated UUIDs, a retry won’t create a duplicate. 501 Not Implemented is not retryable — the operation isn’t supported, so adjust the request instead.
- Quotes expire after 2 minutes — refresh the quote rather than retrying the order.
- Expired Stellar transactions (
tx_too_late) — don’t resubmit the same XDR; regenerate it (see Stellar) and submit the fresh one.
Still stuck? Book a session with the team.