# Solicitudes y errores > Cómo son las solicitudes y las respuestas de la API de Ora, qué significa cada error y cuáles son los límites de frecuencia. ### Solicitudes y respuestas - **JSON de entrada, JSON de salida.** Envía `Content-Type: application/json` cuando hay un cuerpo, y solo cuando lo hay. - **Envoltorio.** Todas las respuestas llevan `"success": true` o `"success": false`. Compruébalo, no solo el código de estado. - **Las cantidades de tokens** van en unidades base en bruto, como *cadenas* decimales, porque desbordan los números de JavaScript: `"250000000000"`. Divídelas entre 10 elevado al número de decimales del token para mostrarlas (la mayoría de los tokens de launchpads de Solana usan 6 decimales; los tokens EVM, 18). - **Cantidades nativas.** Los campos de entrada con nombre `…Sol` son números decimales simples del activo de gas de la chain (`0.5`). Las cantidades nativas en bruto de las respuestas van en lamports en Solana y en wei en las chains EVM. - **Direcciones.** Las direcciones de Solana van en base58; las direcciones EVM, en hexadecimal con `0x`. En una ruta, `{address}` y `{mint}` son el mint (Solana) o el contrato (EVM) de un token. - **ID de solicitud.** Todas las respuestas llevan una cabecera `X-Request-ID`. Envía el tuyo (un UUID v4) para vincular una llamada con tus logs; Ora lo propaga por todos los servicios por los que pasa. - **Las marcas de tiempo** van en ISO 8601, en UTC. ### Errores Una llamada fallida responde con `"success": false` y un `error`. Cuando Ora reenvía el fallo de uno de sus servicios, `error` es un código de referencia corto (como `M4K8T`) y `message` contiene el motivo legible. ```json { "success": false, "error": "M4K8T", "message": "…readable reason…" } ``` | Estado | Significado | Qué hacer | |---|---|---| | `400` | El cuerpo o un parámetro no es válido. | Lee `error` y `message`: indican el campo. No reintentes sin cambiar nada. | | `401` | Falta la clave, está mal formada, o se rotó o se revocó. | Revisa la cabecera y la clave. No reintentes en bucle: las claves rechazadas tienen un límite de frecuencia por IP. | | `403` | El acceso a la API está desactivado en la cuenta. | Pide al soporte de Ora que active el acceso a la API. | | `404` | No existe, o no es tuyo. Ora nunca revela si existe algo que no te pertenece. | Revisa el ID o la dirección, y que pertenezca a tu cuenta. | | `409` | El recurso no está en un estado que lo permita (aún no lanzado, ya en marcha...). | Lee el estado y luego actúa. | | `429` | Límite de frecuencia alcanzado. | Reduce el ritmo: consulta [Límites de frecuencia](#rate-limits). | | `502` | Un servicio detrás de la API ha fallado. | Reintenta con backoff. Si persiste, envía el código `error` y el `X-Request-ID` al soporte de Ora. | | `503` | No disponible temporalmente (una dependencia está caída u ocupada). | Reintenta con backoff. | > **Warning:** **Las escrituras no son idempotentes.** Un `502` o un timeout en una compra, una venta o un lanzamiento no significa que no haya pasado nada. Lee el estado (posiciones, operaciones, el stream del token) antes de reintentar una escritura. ### Límites de frecuencia | Cupo | Límite | Se cuenta por | Cubre | |---|---|---|---| | Solicitudes a la API | 100 por minuto | Cuenta | Todas las solicitudes hechas con tu clave, streams incluidos (una por conexión). Es independiente del cupo propio de la app: un script muy activo nunca ralentiza tu sesión en la app. | | Claves rechazadas | 20 por minuto | Dirección IP | Las solicitudes cuya clave está mal formada o es desconocida (`401`). Superado el límite, reciben un `429`. | Las ventanas son fijas, de un minuto. Un `429` no lleva cabecera `Retry-After`: espera y luego reintenta con backoff exponencial, empezando en 1 segundo y con un máximo de 60. Reparte los trabajos por lotes en el tiempo en lugar de enviarlos en ráfagas. ```js title="retry.mjs" export async function withRetry(fn, tries = 6) { for (let i = 0; ; i++) { try { return await fn(); } catch (err) { const retryable = err.status === 429 || err.status === 502 || err.status === 503; if (!retryable || i + 1 >= tries) throw err; await new Promise((r) => setTimeout(r, Math.min(60_000, 1000 * 2 ** i))); } } } // Reads only. Before retrying a write, check what already happened. ```