> Chytapay is a bank-transfer payments platform in Argentina. This page is part of the Integration API docs: https://chytapay.com.ar/api/
> Recommended reconciliation: by CUIL. Environments: test (https://integration-api.test.chytapay.com.ar) and production (https://integration-api.chytapay.com.ar).
> Page: "Operations and errors" (https://chytapay.com.ar/api/en/operacion/), updated on 2026-10-09.
> Full index for AI assistants: https://chytapay.com.ar/llms.txt

# Operations and errors

Environments, go-live checklist, usage limits, errors by endpoint and downloads for the Integration API.

The reference data for running your integration: environments, limits, errors and downloads.

1. [Environments](https://chytapay.com.ar/api/en/operacion/#ambientes): Sandbox and Production
2. [Going live](https://chytapay.com.ar/api/en/operacion/#produccion): what to check before you collect
3. [Limits](https://chytapay.com.ar/api/en/operacion/#limites): WhatsApp messages and the CVU pool
4. [Errors](https://chytapay.com.ar/api/en/operacion/#errores): what each endpoint returns

## Environments and URLs

Your integration has two environments, Sandbox and Production, with their own credentials. You manage both from the same portal, [chytapay.com.ar/portal/login](https://chytapay.com.ar/portal/login), with the environment selector.

| Service                                       | Sandbox                                        | Production                                |
| --------------------------------------------- | ---------------------------------------------- | ----------------------------------------- |
| Integration API (charges, bulk, payer-lookup) | `https://integration-api.test.chytapay.com.ar` | `https://integration-api.chytapay.com.ar` |
| Auth API (OAuth: `/integration/oauth2/*`)     | `https://auth-api.test.chytapay.com.ar`        | `https://auth-api.chytapay.com.ar`        |
| Widget publishable key                        | `pk_test`                                      | `pk_live`                                 |

The Integration API mounts its routes at the root: `/payment-request`, `/payment-request/bulk` and `/payer-lookup`. The widget uses `/v1/payments` on the same host.

Test tokens, the test webhook and payment simulation exist only in Sandbox. In Production, `livemode` is `true` only for a real payment.

## Going live

You request Production under [**Credenciales**](https://chytapay.com.ar/portal/credentials) (Credentials): if the automatic check approves it, you generate the production credentials with the environment selector on Production, and if not, the request goes to review. Nothing from Sandbox carries over. Before you collect, check:

1. **Credentials.** Generate them under [**Credenciales**](https://chytapay.com.ar/portal/credentials) (Credentials) and use your production `clientId` and `clientSecret` against `auth-api.chytapay.com.ar`, and the `pk_live` if you use the widget (the `sk_live` only if you create charges through `/v1/payments`).
2. **Linked merchants.** Sandbox links don't exist in production: each merchant repeats the OAuth flow in [Connect merchant accounts](https://chytapay.com.ar/api/en/conectar-comercios/).
3. **Webhooks.** Set the URL under [**Configuración**](https://chytapay.com.ar/portal/settings) (Settings) with the environment on Production, verify the signature with the production secret, and enable `payment.unmatched` if you need it, since it's opt-in. See [delivery guarantees](https://chytapay.com.ar/api/en/webhooks/#entrega) and [subscriptions](https://chytapay.com.ar/api/en/webhooks/#suscripcion).
4. **Errors.** Handle 409, 429 and timeouts with the [retries](https://chytapay.com.ar/api/en/operacion/#reintentos) table.
5. **Tokens and events.** Renew each merchant account's `idToken` with the `refreshToken` before the hour is up, deduplicate by `X-Chytapay-Webhook-Id` and return `2xx` within 5 seconds.

### Retries on your side

There is no idempotency key. The `referenceId` prevents duplicates: it's unique per integration and merchant account, canceled charges included.

| Situation                      | What to do                                                                                                              |
| ------------------------------ | ----------------------------------------------------------------------------------------------------------------------- |
| Timeout or 5xx on a create     | `GET /payment-request/{referenceId}`: on 404, retry with the same `referenceId`.                                        |
| 409 `ReferenceIdAlreadyExists` | It was already created. Retrieve it with GET; don't generate a new `referenceId`.                                       |
| 429 on create or bulk          | Don't retry in a loop: wait until 00:00 Argentina time. A bulk that doesn't fit entirely under the cap creates nothing. |
| Timeout or 5xx on a bulk       | Retrieve one `referenceId` from the batch with GET: bulk is all or nothing.                                             |
| 422 on a retried bulk          | If the reason is `The referenceId already exists for this integration`, the earlier batch was created.                  |
| 503 on payer-lookup            | ARCA didn't respond. Retry, or continue without validating the payer.                                                   |

The create example with timeout and 409 is in [Create charges](https://chytapay.com.ar/api/en/crear-cobros/#duplicados).



## Limits

The only daily cap when creating charges is the WhatsApp message cap. There is no cap on requests or on charges created per day. It resets at 00:00 Argentina time (UTC-3).

| Cap                                 | Value                                                                                                                                                                                                                                             | When exceeded                                         |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------- |
| Your integration's messages         | Per integration, all its merchants added together: 20 per day in Sandbox and 200 initial per day in Production. Raise it with **Pedir más límite** (Request more limit), on the portal [**Dashboard**](https://chytapay.com.ar/portal/dashboard). | 429 `IntegrationDailyRequestLimitExceededError`       |
| Messages shared across integrations | One global daily cap                                                                                                                                                                                                                              | 429 `IntegrationGlobalDailyMessageLimitExceededError` |

### What counts as a WhatsApp message

Each charge created with `sendWhatsappNotification: true` counts as one message. Charges that don't ask for a WhatsApp notification don't use the cap. A bulk that doesn't fit entirely under the cap creates nothing.

### The 429 response from the message caps

The body carries `code` (which of the two caps) and `message`. Your integration's cap adds `availableAt` (the reset, in Argentina time), `maxRequestsPerDay` and `maxMessagesPerDay`. The global one adds `requestedMessages` and `availableAtUnixSeconds` (the reset, in Unix seconds). If the cap can't be checked, create and bulk answer 503 `IntegrationDailyLimitUnavailableError`: retry in a few minutes. The reset is at 00:00 Argentina time: don't retry in a loop, wait until then. With parallel creates near the cap, a charge can be created even though it returned 429: check with GET before recreating it.

### Other limits

| Limit                          | Value                          | When exceeded                         |
| ------------------------------ | ------------------------------ | ------------------------------------- |
| Items per bulk                 | 1 to 100 per call              | 400 `ValidationError`                 |
| CVU pool, per merchant account | Up to 100 per merchant account | 400 `InsufficientActiveAccountsError` |

### Payer-lookup

`GET /payer-lookup?document=` has its own quota, separate from the creation caps: 1000 units per day, per integration and merchant account, reset at 00:00 Argentina time. A CUIL or CUIT costs 1 and a DNI costs 2, because Chytapay queries ARCA for both possible CUILs. When exceeded, 429 `PayerLookupDailyLimitExceededError`.

- Don't consume: a 400 for an invalid `document`, and a 503 answered without querying ARCA.
- Do consume: a 200 with `name: null`, and a 503 because ARCA didn't respond.
- The 429 includes `code`, `message`, `availableAtUnixSeconds` (the reset, in Unix seconds) and `maxLookupsPerDay` (`1000`).

See how to [validate the payer](https://chytapay.com.ar/api/en/conciliacion/#validar-pagador).

### CVU pool

The pool belongs to the merchant account, is shared by all its integrations and is taken up by the CVUs of open charges. If no CVU is free, create and bulk return 400 `InsufficientActiveAccountsError` and create nothing. When a charge closes, its CVU goes back to the pool. See how this affects each mode in [Reconciliation](https://chytapay.com.ar/api/en/conciliacion/).



## Errors by endpoint

Decide by the HTTP status, then by `code` or `error`, never by the text of `message`. The tables follow the [OpenAPI spec](https://chytapay.com.ar/api/en/operacion/#openapi).

### Error body format

There is no request id header. The `id` comes in the body, only in the general shape: log it. Most messages are in English.

| Body shape                                 | When                                                                                                           |
| ------------------------------------------ | -------------------------------------------------------------------------------------------------------------- |
| `{ code, message, id }`                    | General shape: business 400, 409 `CustomerAlreadyAssociatedError`, 500                                         |
| `{ code, message, id, validationDetails }` | 400 `ValidationError`. `validationDetails` is a list of `{ field, message }`; `message` repeats the first one. |
| `{ error, message, referenceId }`          | 409 from create                                                                                                |
| `{ message, errors }`                      | 422 from bulk. `errors` is a list of `{ index, referenceId, reason }`.                                         |
| `{ error, message, data }`                 | 409 from PATCH, payer PATCH and cancel                                                                         |
| `{ message }`                              | 404 for a nonexistent charge, an integration not ready to collect or a location                                |
| `{ code, message }`                        | 503 from payer-lookup                                                                                          |
| Plain text, not JSON                       | 400, 403 and 404 from the token check                                                                          |

### Common to all endpoints

| HTTP | Body                                                | When it happens and what to do                                                                                                                           |
| ---- | --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 401  |                                                     | Missing, invalid or expired token. Renew it with the refresh token from [Connect merchant accounts](https://chytapay.com.ar/api/en/conectar-comercios/). |
| 400  | `Bad request: Missing required authentication data` | The token doesn't carry the account, role or application. Send the merchant's `id_token` in `Authorization: Bearer`.                                     |
| 404  | `Integration client not found`                      | The token belongs to another application. Request it with your integration's `clientId` in that environment.                                             |
| 403  | `Not authorized as user of integration client`      | The merchant account isn't linked, or was unlinked. Link it through OAuth.                                                                               |
| 500  | `{ code, message, id }`                             | Internal error. On a create or bulk, check with GET before retrying.                                                                                     |

### Create a charge: `POST /payment-request`

| HTTP | `code` or `error`                                                                                | When it happens and what to do                                                                                      |
| ---- | ------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------- |
| 400  | `ValidationError`                                                                                | A field is missing, has an invalid type or range, or this `type` doesn't accept it. See `validationDetails`.        |
| 400  | `WebhookUrlBlockedError`                                                                         | `webhookUrl` points to an internal or private address.                                                              |
| 400  | `InsufficientActiveAccountsError`                                                                | No free CVU in the [merchant's pool](https://chytapay.com.ar/api/en/operacion/#pool-cvus).                          |
| 409  | `ReferenceIdAlreadyExists`                                                                       | The `referenceId` already exists, even if that charge is canceled. The charge isn't returned: retrieve it with GET. |
| 429  | `IntegrationDailyRequestLimitExceededError` or `IntegrationGlobalDailyMessageLimitExceededError` | You reached the WhatsApp message cap. See [the limits](https://chytapay.com.ar/api/en/operacion/#respuesta-429).    |
| 409  | `CustomerAlreadyAssociatedError`                                                                 | Two simultaneous creates for the same payer collided. Check with GET and retry if it doesn't exist.                 |

### Create charges in bulk: `POST /payment-request/bulk`

If the bulk fails, no charge in the batch is created.

| HTTP | `code`                                                                                           | When it happens and what to do                                                                                                          |
| ---- | ------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------- |
| 400  | `ValidationError`                                                                                | Empty batch or more than 100 items, an item breaks the contract, or a due date has a time (only `YYYY-MM-DD`). See `validationDetails`. |
| 400  | `InsufficientActiveAccountsError`                                                                | The [merchant's pool](https://chytapay.com.ar/api/en/operacion/#pool-cvus) isn't large enough for the batch.                            |
| 404  |                                                                                                  | The integration isn't ready to collect and retrying won't fix it. Contact support.                                                      |
| 429  | `IntegrationDailyRequestLimitExceededError` or `IntegrationGlobalDailyMessageLimitExceededError` | The batch doesn't fit entirely under the WhatsApp message cap: nothing is created.                                                      |
| 422  |                                                                                                  | Items that fail business validation, all listed in `errors`. Fix them and resend the full batch.                                        |

The 422 `reason` values are `Duplicate referenceId within the batch`, `The referenceId already exists for this integration`, `The taxDocument does not resolve to a valid CUIL` and `Duplicate payer within the batch` (the same document in more than one item).

### Retrieve a charge: `GET /payment-request/{referenceId}`

| HTTP | Body                                         | When it happens and what to do                                                                                                   |
| ---- | -------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| 404  | `{ "message": "Payment request not found" }` | No charge with that `referenceId` for this integration and merchant account. Check that the token belongs to the right merchant. |

### Set the amount: `PATCH /payment-request/{referenceId}`

| HTTP | `code` or `error`                | When it happens and what to do                                                                          |
| ---- | -------------------------------- | ------------------------------------------------------------------------------------------------------- |
| 400  | `ValidationError`                | `amount` is missing, isn't positive, has more than 2 decimals or exceeds 200,000,000.                   |
| 404  |                                  | The charge doesn't exist.                                                                               |
| 409  | `PaymentRequestCannotBeModified` | The charge isn't in `draft`, or already received payments: only a draft with no payments accepts PATCH. |

### Correct the payer: `PATCH /payment-request/{referenceId}/customer`

| HTTP | `code` or `error`                        | When it happens and what to do                                                                                       |
| ---- | ---------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| 400  | `ValidationError`                        | `taxDocument` is missing or invalid (format or check digit), or `name`, `email` or `phoneNumber` break the contract. |
| 404  |                                          | The charge doesn't exist, or the integration isn't ready to collect.                                                 |
| 409  | `PaymentRequestCustomerCannotBeModified` | The payer can't be changed. The reason is in `data.reason`.                                                          |

| `data.reason`                     | Meaning                                                             |
| --------------------------------- | ------------------------------------------------------------------- |
| `conciliation_type_not_cuil`      | The charge uses CVU mode, which doesn't store the payer's document. |
| `state_not_modifiable`            | The charge is in a final state.                                     |
| `payment_already_received`        | The charge already received money.                                  |
| `no_collision_free_account`       | No CVU can hold the new document. Nothing was changed.              |
| `missing_notification_contact`    | The new payer lacks the contact the reminders require.              |
| `incomplete_payment_request_data` | The charge has no associated payer.                                 |
| `concurrent_modification`         | A concurrent change. Read the charge again and retry.               |

See when to use it in [correct the payer](https://chytapay.com.ar/api/en/conciliacion/#corregir-pagador).

### Cancel a charge: `POST /payment-request/{referenceId}/cancel`

| HTTP | `error`                          | When it happens and what to do                                                                        |
| ---- | -------------------------------- | ----------------------------------------------------------------------------------------------------- |
| 404  |                                  | The charge doesn't exist.                                                                             |
| 409  | `PaymentRequestCannotBeCanceled` | The charge isn't in `draft` or `pending`: it has partial payments, or it's paid, expired or canceled. |

### Validate a document: `GET /payer-lookup`

| HTTP                  | `code`                                | When it happens and what to do                                                              |
| --------------------- | ------------------------------------- | ------------------------------------------------------------------------------------------- |
| 200 with `name: null` |                                       | ARCA responded and the document has no holder. Ask the payer to check it.                   |
| 400                   | `ValidationError`                     | `document` isn't an 11-digit CUIL or CUIT, or a 7 or 8-digit DNI.                           |
| 404                   |                                       | The account isn't linked.                                                                   |
| 429                   | `PayerLookupDailyLimitExceededError`  | You reached the 1000 units for the day.                                                     |
| 503                   | `PayerLookupProviderUnavailableError` | ARCA couldn't be queried: the payer wasn't verified. Retry, or continue without validating. |
| 503                   | `PayerLookupQuotaUnavailableError`    | The quota couldn't be checked. Retry.                                                       |

### Assign the location: `PUT /my-integration/tenant`

| HTTP | Body                                                                           | When it happens and what to do                                                                                                     |
| ---- | ------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| 400  | `ValidationError`                                                              | `tenantKey` is missing or empty.                                                                                                   |
| 404  | `{ "message": "The specified tenant does not exist or was deleted" }`          | The location doesn't exist, was deleted or belongs to another integration. See [Locations](https://chytapay.com.ar/api/en/sedes/). |
| 404  | `{ "message": "No integration account was found for the authenticated user" }` | The merchant account isn't linked.                                                                                                 |

### OAuth

The errors for `authorize`, `token`, `refresh` and `revoke` are in [Connect merchant accounts](https://chytapay.com.ar/api/en/conectar-comercios/).

## Common mistakes

- **Using the wrong token.** The Integration API takes the merchant account's `id_token`, not the integration admin's token or the `clientSecret`.
- **Recreating after a timeout or retrying a 429 in a loop.** See [retries](https://chytapay.com.ar/api/en/operacion/#reintentos) and [the 429 response](https://chytapay.com.ar/api/en/operacion/#respuesta-429).
- **Reading `name: null` as an ARCA failure.** The document has no holder; the failure is the 503.

## Downloads

### OpenAPI

Import the spec into Postman, Insomnia, Bruno or any API client, or browse the [API Reference](https://chytapay.com.ar/api/reference/):

- Integration API: `https://public-api.chytapay.com.ar/integration-api-swagger`
- Auth API: `https://public-api.chytapay.com.ar/auth-api-swagger`

The spec still declares 10,000,000 as the amount cap for PATCH; the API enforces 200,000,000.

### Postman collection

It includes a Sandbox environment (the file is named `Test`) and a Production one, with the hosts set. It covers all the charge endpoints, payer-lookup and payer correction, with example dates that are always in the future.

- Collection: `/api/assets/postman/Chytapay-Integration-API.postman_collection.json`
- Test environment: `/api/assets/postman/Chytapay-Test.postman_environment.json`
- Production environment: `/api/assets/postman/Chytapay-Production.postman_environment.json`

## Frequently asked questions

### Are the limits and the pool per merchant or per integration?

The message cap is per integration (all its merchants added together). The payer-lookup quota is per integration and merchant account. The CVU pool is per merchant account. More answers in [Frequently asked questions](https://chytapay.com.ar/api/en/preguntas-frecuentes/).

- [Create charges](https://chytapay.com.ar/api/en/crear-cobros/): Fields, states, duplicates and bulk.
- [Webhooks](https://chytapay.com.ar/api/en/webhooks/): Signature, retries and deduplication.
- [Connect merchant accounts](https://chytapay.com.ar/api/en/conectar-comercios/): OAuth, tokens and their errors.
- [Reconciliation](https://chytapay.com.ar/api/en/conciliacion/): CUIL, payer-lookup and unmatched payments.
