---
title: Buenas prácticas
description: Cree una integración fiable con la API de Clipia — reintentos idempotentes, webhooks en lugar de consultas de estado, gestión de errores y de 429, estimación del coste y almacenamiento del request_id.
icon: BadgeCheck
---

Una integración fiable con la API de Clipia y con costes predecibles se reduce a cinco prácticas: haga que los envíos sean idempotentes, prefiera los webhooks a las consultas de estado, gestione los errores y el `429` con espera progresiva, estime el coste antes de enviar y guarde el `request_id` en su sistema.

## Reintentos idempotentes [#idempotency]

Envíe un `Idempotency-Key` con cada envío: un UUID v4 único por solicitud **lógica**. Si se pierde la conexión, reintente con la misma clave y el mismo cuerpo: recibirá el **mismo** `request_id`, sin segunda generación ni segundo cobro. Una clave de idempotencia dura 24 horas dentro de una misma clave de API.

```bash
curl -X POST https://api.clipia.ai/v1/models/nano-banana-2 \
  -H "Authorization: Bearer $CLIPIA_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 8f3a1c7e-2b41-4d2a-9c0e-1200304cf45b" \
  -d '{ "input": { "prompt": "a sunset over mountains, cinematic" } }'
```

| Situación | Resultado |
| --- | --- |
| Misma clave, mismo cuerpo | El mismo `request_id`, sin segundo cobro |
| Misma clave, modelo o cuerpo distintos | `409 idempotency_key_reuse` |
| Reintento mientras la primera solicitud sigue en proceso | `409 request_in_progress`: reintente en unos segundos |

<Callout type="warn" title="Una clave por solicitud lógica">
Cree un UUID nuevo para cada nueva generación, no para cada intento de red. Los SDK añaden por su cuenta una clave aleatoria, pero para reintentar de forma segura, pase su propia clave y reutilícela. No incluya datos personales en la clave. Consulte [Idempotencia](/es/docs/api-reference/idempotency).
</Callout>

## Webhooks en lugar de consultas de estado [#webhooks]

Indique un `webhook_url` (solo `https://`) al enviar y Clipia enviará un `POST` cuando la tarea termine, de modo que no necesita consultar el estado. Mantenga la consulta del estado como alternativa de respaldo y no consulte más de una vez cada 1–3 segundos.

- Responda con `2xx` en un plazo de 10 segundos; de lo contrario, la entrega se reintenta, hasta 6 intentos con pausas crecientes.
- Verifique `X-Clipia-Signature` (HMAC-SHA256) en cada entrega. Cada clave de API tiene su propio secreto de webhooks.
- Gestione las entregas de forma **idempotente** por `request_id`: la misma entrega puede llegar más de una vez.

Consulte [Webhooks](/es/docs/api-reference/webhooks).

## Errores y 429 [#errors]

Los errores comparten un único formato: un objeto `error` con `type`, `code` y `message`. Decida qué hacer según el estado HTTP y el `code`.

| HTTP | `code` | Qué hacer |
| --- | --- | --- |
| `400` / `422` | `invalid_request` / `model_input_invalid` | Corrija el cuerpo o los parámetros; no reintente sin cambios |
| `401` / `403` | `invalid_api_key` / `insufficient_scope` | Compruebe la clave y sus permisos |
| `402` | `insufficient_credits` | Recargue el saldo |
| `409` | `request_in_progress` | Reintente en unos segundos con la misma clave de idempotencia |
| `429` | `rate_limit_exceeded` | Espere `Retry-After` segundos y reintente |
| `429` | `concurrency_limit_exceeded` | Espere a que termine alguna de sus tareas |
| `500` / `503` | `internal_error` / `service_unavailable` | Reintente con espera progresiva |

Ante un `429`, guíese por `Retry-After` y las cabeceras `RateLimit-*`. `RateLimit-Reset` es el momento en que se restablece la ventana, en segundos Unix, no el número de segundos que faltan:

```http
RateLimit-Limit: 120
RateLimit-Remaining: 0
RateLimit-Reset: 1760011260
Retry-After: 37
```

<Callout type="info" title="Espera exponencial con variación aleatoria">
Ante `429`, `500` y `503`, reintente con pausas crecientes más una variación aleatoria (por ejemplo, 1, 2, 4 y 8 segundos, con un máximo de cinco intentos) para que los reintentos de distintos clientes no coincidan. Los límites predeterminados son 120 solicitudes por minuto por clave y 600 entre todas las claves de una cuenta. El límite de concurrencia solo se aplica si se ha configurado para la clave o la cuenta. Consulte [Límites de frecuencia](/es/docs/api-reference/rate-limits).
</Callout>

## Estime el coste antes de enviar [#estimate]

Para conocer el precio de un conjunto concreto de parámetros sin poner nada en cola, llame a `POST /v1/models/{model}/estimate`: devuelve `credits`. Utilícelo para mostrar el precio a sus usuarios o para bloquear de antemano las solicitudes caras. Al enviar, el campo `cost` contiene la cantidad reservada para la tarea; si el saldo es insuficiente, el envío devuelve `402`. Consulte [Estimación del coste](/es/docs/api-reference/estimate).

<Callout type="info" title="Precios">
Los precios están vigentes a octubre de 2026. El coste exacto siempre se muestra en el botón de ejecución antes de que se cobre nada.
</Callout>

## Guarde el request_id [#request-id]

Guarde el `request_id` de cada envío en su base de datos justo después de la respuesta. Lo necesita para:

- asociar un webhook entrante con su propia entidad;
- consultar `status_url` o `response_url` cuando sea necesario;
- evitar procesar dos veces la misma entrega.

<Callout type="warn" title="Asocie Idempotency-Key con request_id">
Guarde el par `Idempotency-Key` → `request_id`. Si se pierde la respuesta a un envío, el reintento con la misma clave devuelve el mismo `request_id` y no aparece ninguna generación duplicada.
</Callout>
