# Errors and retries

Every refusal is `{ error: { code, message, requestId } }`. Branch on `code`, show or log `message`, quote `requestId` if you write to us.

```json
{
  "error": {
    "code": "insufficient_credits",
    "message": "This account has no credit left to unlock the image.",
    "requestId": "req_8Gq2Lw0fTz1kVb6s"
  }
}
```

## When to retry

- `429`: wait the `Retry-After` seconds, then send the same request.
- `500` and `503`: wait a moment and retry with the same `Idempotency-Key`: it is never charged twice.
- Every other `4xx`: fix the request first. The same request gets the same answer.

## Every code

Generated from the API's own registry, the list every answer is checked against.

| Status | Code | What it means | What to do |
| --- | --- | --- | --- |
| 400 | `captcha_failed` | The challenge was not passed. | Complete the challenge again, then send the request. |
| 400 | `code_invalid` | The sign-in code is wrong, used or expired. | Ask for a new code. |
| 400 | `confirmation_required` | Erasing an account needs the typed confirmation in the body. | Send the exact phrase the reference shows. |
| 400 | `dimensions_too_large` | The image is wider or taller than we convert. | Send an image of at most the limit on each side. |
| 400 | `file_empty` | The file has no bytes. | Upload the file again. |
| 400 | `file_too_large` | The file is over the size limit. | Send a smaller file. |
| 400 | `format_unavailable` | This result has no file in that format. | Ask for one of the formats the conversion lists. |
| 400 | `input_hash_mismatch` | The inputHash you sent is not the hash of the stored file. | Upload the file again; the stored bytes are not the ones you meant. |
| 400 | `invalid_colors` | A color mapping names a color the result does not have, or is not a hex color. | Map only the result's own colors, as #rrggbb. |
| 400 | `invalid_country` | The country is not a two-letter ISO 3166 code. | Send a code like US or SG, or leave it out. |
| 400 | `invalid_cursor` | The page cursor is not one this list returned. | Start again from the first page, or pass the nextCursor you were given. |
| 400 | `invalid_email` | That is not an email address. | Check the address and send it again. |
| 400 | `invalid_filter` | The list filter is not one this list offers. | Use one of the filters the reference names. |
| 400 | `invalid_id` | An id in the path is not a UUID. | Use the id exactly as the API returned it. |
| 400 | `invalid_idempotency_key` | The idempotency key is too short, too long or has characters we do not take. | Send a UUID, or 8 to 200 letters, digits and . _ : ~ - |
| 400 | `invalid_input_key` | That upload does not belong to this account. | Upload the file with this account, then convert it. |
| 400 | `invalid_options` | An option is out of bounds or not offered yet. | Read the message for the bounds, or leave the option out. |
| 400 | `invalid_palette` | The palette's name or colors cannot be taken. | Give it a name and 1 to 24 distinct #rrggbb colors. |
| 400 | `invalid_request` | A field is missing, has the wrong type, or is not one this endpoint takes. | Read the message: it names the field. Fix it and send again. |
| 400 | `invalid_size` | The declared size is not a positive whole number of bytes. | Send the file's exact size in bytes. |
| 400 | `invalid_sort` | The list order is not one this list offers. | Use one of the orders the reference names. |
| 400 | `invalid_tiles` | A tile asked for a layer, level or position this result does not have. | Ask only for tiles inside the result's levels. |
| 400 | `invalid_token` | The link's token is malformed, expired or already used. | Ask for a new link. |
| 400 | `invalid_url` | We do not fetch that URL: only https on the standard port, with no user name or password, on the public internet. | Send a public https link to the image, or the image itself. |
| 400 | `invalid_verdict` | The verdict's vote, reasons or note cannot be taken. | Read the message: it names the field. |
| 400 | `layer_unavailable` | This result has no such layer. | Ask for a layer the reference names. |
| 400 | `malformed_body` | The body is missing, or is not a JSON object (or, where the endpoint takes a file, form data). | Send a JSON object with Content-Type: application/json, or multipart/form-data where the endpoint takes a file. |
| 400 | `malformed_image` | The file is not a readable image of the type it claims. | Export the image again and send that file. |
| 400 | `same_plan` | The account is already on that plan level. | Nothing to do. Pick another level to change it. |
| 400 | `unknown_pack` | There is no credit pack by that name. | Use one of the items GET /prices lists. |
| 400 | `unknown_plan` | There is no plan level by that name. | Use one of the plan items GET /prices lists. |
| 400 | `unknown_preset` | There is no preset by that name. | Use one of the presets the message lists. |
| 400 | `unknown_provider` | That is not a way to sign in here. | Use one of the methods GET /session offers. |
| 400 | `unsupported_type` | We do not convert that kind of file. | Send one of the formats the message lists. |
| 400 | `url_unreachable` | We could not fetch the image at that URL: no answer, a missing page, too slow, too many redirects, or too large. | Read the message for which. Check the link opens in a private window, or send the image itself. |
| 401 | `invalid_api_key` | The API key is unknown, revoked, past its end, or mistyped. | Copy the key again, or make a new one on the developer page. |
| 401 | `unauthenticated` | Nobody is signed in, or the session or key is not valid. | Sign in again, or send a valid key as Authorization: Bearer. |
| 402 | `insufficient_credits` | There are not enough credits for this unlock. None was spent. | Buy credits, then send the same request again. |
| 402 | `unlock_required` | This image is not unlocked yet, so its files do not download. | Unlock it (1 credit, once per image), then download. |
| 403 | `account_required` | Trying without an account does not include this. | Sign in or create an account. The conversions come with you. |
| 403 | `api_key_not_allowed` | An API key cannot do this: it manages the account, so only its signed-in owner may. | Do it on vecsnap.com, signed in. |
| 403 | `email_unverified` | The sign-in provider has not verified this email address. | Verify the address with the provider, or sign in with the email code. |
| 403 | `forbidden` | This caller may not do that. | Read the message: it says who may. |
| 403 | `plan_required` | Live API keys and live webhooks come with the Pro plan, and this account is not on Pro. | Choose Pro, or use test mode: it is free. |
| 404 | `api_key_not_found` | There is no such key in this account. | Use a key id GET /api-keys listed. |
| 404 | `no_plan` | This account has no plan to act on. | Subscribe first. |
| 404 | `not_found` | There is nothing at that id for this caller. | Check the id. Another account's objects read as not found too. |
| 404 | `original_unavailable` | This conversion's original is not shown here. | Show its redraw instead. |
| 404 | `palette_not_found` | There is no such palette in this account. | Use a palette id GET /palettes listed. |
| 404 | `variant_not_found` | There is no such recolor of this result. | Use a variant id this result listed. |
| 404 | `webhook_delivery_not_found` | There is no such webhook delivery in this account. | Use a delivery id GET /webhook-deliveries listed. |
| 404 | `webhook_endpoint_not_found` | There is no such webhook endpoint in this account. | Use an endpoint id GET /webhook-endpoints listed. |
| 409 | `account_exists` | An account already holds this email address under another spelling. | Sign in with that account. |
| 409 | `already_signed_in` | An account is already signed in here. | Sign out first to start a guest. |
| 409 | `already_subscribed` | This account already has a plan. | Change the plan instead of buying another. |
| 409 | `api_key_limit` | The account has the most keys of this mode it can keep. | Revoke a key you no longer use, then make the new one. |
| 409 | `conversion_failed` | The conversion ended without a result. | Convert the image again. Converting is free. |
| 409 | `conversion_running` | The image is still converting. | Wait for it to finish, then try again. |
| 409 | `idempotency_key_reused` | That idempotency key was used for a different request. | Make a new key for a new request. |
| 409 | `not_deleted` | The image is not in Recently deleted. | Delete it first, or leave it. |
| 409 | `not_in_test_mode` | Test mode makes the conversion and its SVG files only. | Use a live key for it, or test the conversion and its SVG files. |
| 409 | `not_ready` | The conversion is still running. | Wait for it to finish (a webhook, the events stream, or a read), then ask again. |
| 409 | `not_waiting` | Only a conversion waiting in line can be canceled. | Let a running conversion finish. |
| 409 | `original_not_kept` | The image's file is no longer kept, so it cannot be converted again. | Upload the file again. |
| 409 | `palette_limit` | The account has the most palettes it can keep. | Delete a palette, then save the new one. |
| 409 | `plan_active` | The account's plan still renews. | Cancel the plan first. |
| 409 | `plan_ending` | The plan is set to end. | Keep the plan first, then change it. |
| 409 | `plan_past_due` | The plan's last payment did not go through. | Update the payment method in the billing portal. |
| 409 | `plan_renewal_pending` | A renewal is being paid right now. | Try again in a few minutes. |
| 409 | `plan_renewing` | The plan renews in the next few minutes. | Try again after the renewal. |
| 409 | `plan_switch_waiting` | A change of plan is already waiting for the next renewal. | Wait for it, or keep the current plan. |
| 409 | `result_outdated` | This result was made before files were kept per format. | Convert the image again. |
| 409 | `too_many_active_jobs` | Your conversions running at once are at their limit. | Wait for one to finish, or send queue: true to wait in line. |
| 409 | `too_many_colors` | This result has too many colors to edit one by one. | Redraw it with fewer colors first. |
| 409 | `unlock_pending` | A conversion of this image is already unlocking it. | Wait for that conversion to finish. |
| 409 | `webhook_delivery_pending` | That delivery did not end in a failure: it was delivered, or it is still on its way. | Retry only a delivery that failed. |
| 409 | `webhook_endpoint_limit` | The account has the most webhook endpoints of this mode it can keep. | Delete an endpoint you no longer use, then add the new one. |
| 422 | `email_refused` | We do not open accounts for that email domain. | Use another address. |
| 429 | `free_capacity_reached` | Everyone's free conversions for today are used. | Come back after Retry-After (UTC midnight), or unlock with a credit. |
| 429 | `free_limit_reached` | Today's free conversions are used. | Come back after Retry-After (UTC midnight), or unlock with a credit. |
| 429 | `rate_limited` | Too many requests in a short time. | Wait the Retry-After seconds, then send it again. |
| 500 | `internal_error` | Something failed on our side. | Send it again. If it keeps failing, quote the requestId to support. |
| 502 | `code_unavailable` | The sign-in email could not be sent just now. | Try again in a minute. |
| 502 | `derive_failed` | A preview file could not be made just now. | Try again. The coarser picture still shows. |
| 502 | `sign_in_failed` | The sign-in provider did not finish the sign-in. | Start the sign-in again. |
| 502 | `sign_in_unavailable` | The sign-in provider could not be reached. | Try again in a minute. |
| 503 | `auth_unavailable` | We could not check who you are just now. You are not signed out. | Send it again in a few seconds. |
| 503 | `billing_unavailable` | Billing could not be reached just now. | Try again in a few minutes. |
| 503 | `checkout_unavailable` | Checkout is not open yet. | Try again later. |
| 503 | `purchases_unavailable` | Purchases are not open on this deployment. | Try again later. |
| 503 | `sign_out_failed` | The session could not be ended just now. | Try again. |

---
This page: https://vecsnap.com/docs/errors
