> ## Documentation Index
> Fetch the complete documentation index at: https://yn-c9bb3266.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Error codes

> Complete reference of error codes returned by Yuno's public API. Verified against the production codebase.

Every Yuno error follows a single envelope. Use this page to look up what each `code` means and how to act on it. For the full conceptual guide and retry strategy see [Error handling](/core-concepts/error-handling).

## Envelope

```json theme={"theme":{"light":"github-dark","dark":"github-dark"}}
{
  "code": "CUSTOMER_ID_DUPLICATED",
  "messages": [
    "A customer with this merchant_customer_id already exists for this account."
  ]
}
```

Top level. `code` is a stable `SCREAMING_SNAKE_CASE` identifier you can branch on. `messages` is always an array of strings. Validation failures put one entry per failed field. There is no `error` wrapper, no singular `message`, no `type`, no `details` field.

## Framework codes (HTTP status defaults)

These are the default `code` values that Yuno's shared Go and Kotlin libraries map to common HTTP statuses. Service code may return a more specific business `code` for the same status (see the resource sections below).

| `code`                     | HTTP  | When                                                                                                               |
| -------------------------- | ----- | ------------------------------------------------------------------------------------------------------------------ |
| `BAD_REQUEST`              | `400` | Generic 400 fallback when no business code applies.                                                                |
| `VALIDATION_ERROR`         | `400` | Schema or constraint validation failed. The `messages` array names every failed field. Emitted by Kotlin services. |
| `INVALID_REQUEST`          | `400` | Request was rejected by the resource's business rules. Emitted by Go services like payment-api.                    |
| `UNAUTHORIZED`             | `401` | Missing or invalid `public-api-key` / `private-secret-key`.                                                        |
| `FORBIDDEN`                | `403` | Authenticated but not allowed to perform the action.                                                               |
| `NOT_FOUND`                | `404` | The route does not exist, or the framework catch all could not match the resource.                                 |
| `METHOD_NOT_ALLOWED`       | `405` | Wrong HTTP verb on the path. (Go)                                                                                  |
| `UNSUPPORTED_METHOD`       | `405` | Same as above on Kotlin services.                                                                                  |
| `REQUEST_TIMEOUT`          | `408` | Request timed out before the service could respond.                                                                |
| `REQUEST_ENTITY_TOO_LARGE` | `413` | Request body exceeds the service limit.                                                                            |
| `UNSUPPORTED_MEDIA_TYPE`   | `415` | `Content-Type` is missing or not JSON.                                                                             |
| `TOO_MANY_REQUESTS`        | `429` | Edge throttling kicked in. Honor `Retry-After`.                                                                    |
| `INTERNAL_ERROR`           | `500` | Unhandled server side error. Safe to retry idempotent operations.                                                  |
| `BAD_GATEWAY`              | `502` | Upstream provider was unreachable or returned a malformed response.                                                |
| `SERVICE_UNAVAILABLE`      | `503` | Service is overloaded or in maintenance.                                                                           |

## Validation framework codes (Kotlin services)

These come from the shared exception handler used by checkout sessions, recipients, payouts, and any service backed by the shared Kotlin library.

| `code`              | HTTP  | Trigger                                                                                  |
| ------------------- | ----- | ---------------------------------------------------------------------------------------- |
| `VALIDATION_ERROR`  | `400` | A required field is missing, an enum value is wrong, or a JSON field has the wrong type. |
| `MISSING_HEADER`    | `400` | A required header (for example `public-api-key` or `private-secret-key`) was not sent.   |
| `MISSING_PARAMETER` | `400` | A required query parameter was not sent.                                                 |
| `INVALID_DATE_TYPE` | `400` | A date field could not be parsed in the expected ISO format.                             |
| `ILLEGAL_ARGUMENT`  | `400` | An argument violates a business invariant outside JSON validation.                       |

## Customer codes

| `code`                    | HTTP  | Meaning                                                                                                                                                                           |
| ------------------------- | ----- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CUSTOMER_ID_DUPLICATED`  | `400` | A customer already exists with the same `merchant_customer_id`. Look up the existing record with [Retrieve Customer by External ID](/api-reference/customers/get-by-external-id). |
| `CUSTOMER_NOT_FOUND`      | `400` | No customer matches the supplied identifier.                                                                                                                                      |
| `INVALID_PARAMETERS`      | `400` | One or more body parameters are invalid.                                                                                                                                          |
| `CONCURRENT_MODIFICATION` | `409` | The record was updated by another caller while your request was in flight. Re fetch and retry.                                                                                    |
| `DATABASE_ERROR`          | `500` | Internal data store error. Retry with backoff.                                                                                                                                    |

## Recipient and marketplace codes

| `code`                          | HTTP  | Meaning                                                                              |
| ------------------------------- | ----- | ------------------------------------------------------------------------------------ |
| `RECIPIENT_NOT_FOUND`           | `400` | No recipient matches the supplied identifier.                                        |
| `EXTERNAL_ID_EXIST`             | `400` | A recipient already exists with the same `merchant_recipient_id`.                    |
| `INVALID_STATE`                 | `400` | The recipient cannot accept this action in its current state.                        |
| `ONBOARDING_ALREADY_EXISTS`     | `400` | An onboarding flow has already started for this recipient.                           |
| `ONBOARDING_NOT_FOUND`          | `400` | No onboarding record matches the supplied identifier.                                |
| `ONBOARDING_RECIPIENT_MISMATCH` | `400` | The onboarding does not belong to the recipient supplied in the request.             |
| `TRANSFER_NOT_FOUND`            | `400` | No transfer matches the supplied identifier.                                         |
| `INVALID_TRANSFER_STATUS`       | `400` | The transfer cannot accept this action in its current state.                         |
| `REQUEST_CANNOT_BE_PROCESSED`   | `400` | The request is structurally valid but cannot be processed against the current state. |

## Provider codes

Errors that originate at a downstream payment provider are surfaced under codes prefixed with `PROVIDER_`. The provider's raw response is reflected through `messages`. The full set defined in `yuno-go-utils-lib/errors/providerErrors.go`:

| `code`                                | Typical cause                                                                               |
| ------------------------------------- | ------------------------------------------------------------------------------------------- |
| `PROVIDER_INVALID_CREDENTIALS`        | Provider rejected Yuno's credentials. Operations team is paged automatically.               |
| `PROVIDER_INVALID_REQUEST`            | Provider rejected the request shape. Check the provider response in `messages`.             |
| `PROVIDER_REQUEST_TIMEOUT`            | Provider did not respond within the timeout window.                                         |
| `PROVIDER_UNSUPPORTED_METHOD`         | The selected payment method is not supported by this provider.                              |
| `PROVIDER_UNAVAILABLE_PAYMENT_METHOD` | The payment method is enabled on Yuno but unavailable on the provider for this transaction. |
| `PROVIDER_AUTHORIZATION_REQUIRED`     | Provider requires extra authorization (often 3DS or PIN).                                   |
| `PROVIDER_UNKNOWN_IP_ADDRESS`         | Provider does not recognize the source IP.                                                  |
| `PROVIDER_INVALID_TOKEN`              | The supplied vaulted token is invalid for this provider.                                    |
| `PROVIDER_TOKEN_IN_USE`               | The vaulted token is already in use by another transaction.                                 |
| `PROVIDER_INVALID_PARAMETERS`         | One or more provider parameters are wrong.                                                  |
| `PROVIDER_MISSING_PARAMETERS`         | The provider requires parameters that were not supplied.                                    |
| `PROVIDER_INVALID_DATE_FORMAT`        | A date passed to the provider failed parsing.                                               |
| `PROVIDER_PAYMENT_NOT_FOUND`          | The provider could not find the referenced payment.                                         |
| `PROVIDER_TRANSACTION_NOT_FOUND`      | The provider could not find the referenced transaction.                                     |
| `PROVIDER_CUSTOMER_NOT_FOUND`         | The provider could not find the referenced customer.                                        |
| `PROVIDER_CHECKOUT_SESSION_NOT_FOUND` | The provider could not find the referenced checkout session.                                |
| `PROVIDER_INTERNAL_ERROR`             | Provider returned a 5xx style error.                                                        |
| `PROVIDER_UNKNOWN_ERROR`              | Provider returned an unrecognized error.                                                    |
| `PROVIDER_INVALID_STATUS`             | The provider rejected the requested status transition.                                      |
| `PROVIDER_COUNTRY_NOT_SUPPORTED`      | The provider does not support the requested country.                                        |
| `PROVIDER_CURRENCY_NOT_ALLOWED`       | The provider does not support the requested currency.                                       |
| `PROVIDER_CUSTOMER_ID_DUPLICATED`     | The provider already has a customer with this id.                                           |
| `PROVIDER_INVALID_AMOUNT`             | The amount is invalid for the provider (often outside min or max).                          |
| `PROVIDER_INVALID_API_VERSION`        | The provider rejected Yuno's API version.                                                   |
| `PROVIDER_CHARGEBACK_IN_PROCESS`      | A chargeback is already in progress on the underlying transaction.                          |
| `PROVIDER_EXPIRED_CREDENTIALS`        | Provider credentials are expired. Operations team is paged automatically.                   |

When you see a `PROVIDER_*` code, the failure happened at the provider, not at Yuno. Inspect `messages` for the provider's raw text. See [Provider errors](/troubleshooting/provider-errors) for per provider mappings.

## What changed from earlier docs

Earlier versions of this page listed codes such as `INVALID_FIELD`, `INVALID_FORMAT`, `MISSING_FIELD`, `INVALID_ENUM`, `INVALID_AMOUNT`, `INVALID_CURRENCY`, `INVALID_COUNTRY`, `INVALID_JSON`, `DUPLICATE_REQUEST`, `INVALID_API_KEY`, `MISSING_AUTH`, `EXPIRED_KEY`, `METHOD_NOT_ENABLED`, `COUNTRY_NOT_ENABLED`, `PERMISSION_DENIED`, `RESOURCE_NOT_FOUND`, `SESSION_NOT_FOUND`, `PAYMENT_NOT_FOUND`, `ALREADY_CAPTURED`, `ALREADY_REFUNDED`, and `RATE_LIMIT_EXCEEDED`. Those codes are not emitted by any production service. They have been removed in favor of the verified set above. If you have a mapping that still references one of them, switch to the closest real code (for example `RATE_LIMIT_EXCEEDED` becomes `TOO_MANY_REQUESTS`, and the various `INVALID_*` validation codes become `VALIDATION_ERROR` or a `PROVIDER_*` code).
