> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cotizave.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Inicio rápido

> Haz tu primera consulta desde el servidor y usa las tasas en tu aplicación.

<span id="paso-1" />

## Crea una API Key

Crea tu cuenta, verifica tu correo y genera una clave en **API Keys** del [dashboard](https://app.cotizave.com). Se muestra una sola vez. Guarda `COTIZAVE_API_KEY` en la configuración privada de tu servidor, sin comillas ni espacios adicionales. Excluye los archivos de secretos de Git.

La clave no debe aparecer en JavaScript del navegador ni en aplicaciones distribuidas a usuarios. Los ejemplos no contienen una credencial válida.

<span id="paso-2" />

## Prepara el cliente del servidor

Guarda el primer ejemplo como `cotizave.mjs` (Node.js 20 o posterior) o el segundo como `cotizave.py` (Python 3.10 o posterior, con `requests` instalado). Los ejemplos de las otras páginas importan estos archivos. Ambos comprueban el estado HTTP, limitan la espera y rechazan redirecciones. No reintentan automáticamente.

<CodeGroup>
  ```javascript cotizave.mjs theme={null}
  export async function cotizave(path, { method = 'GET', body } = {}) {
    const key = process.env.COTIZAVE_API_KEY?.trim();
    if (!key) throw new Error('Set COTIZAVE_API_KEY on the server');
    const url = new URL(path, 'https://api.cotizave.com');
    if (url.origin !== 'https://api.cotizave.com' || !url.pathname.startsWith('/v1/')) {
      throw new Error('Invalid Cotizave API path');
    }
    const response = await fetch(url, {
      method,
      headers: {
        'X-API-Key': key,
        Accept: 'application/json',
        ...(body === undefined ? {} : { 'Content-Type': 'application/json' })
      },
      ...(body === undefined ? {} : { body: JSON.stringify(body) }),
      redirect: 'error',
      signal: AbortSignal.timeout(10_000)
    });
    let data;
    try { data = await response.json(); } catch { data = null; }
    if (!response.ok || data === null) {
      const error = new Error(`Cotizave HTTP ${response.status}`);
      error.status = response.status;
      error.code = data?.code ?? 'invalid_response';
      error.field = data?.field;
      error.details = data?.details;
      error.scope = response.headers.get('X-RateLimit-Scope');
      error.retryAfter = response.headers.get('Retry-After');
      error.reset = response.headers.get('X-RateLimit-Reset');
      throw error;
    }
    return data;
  }
  ```

  ```python cotizave.py theme={null}
  import os
  import requests

  class CotizaveError(Exception):
      def __init__(self, response, data):
          super().__init__(f"Cotizave HTTP {response.status_code}")
          payload = data if isinstance(data, dict) else {}
          self.status = response.status_code
          self.code = payload.get("code", "invalid_response")
          self.field = payload.get("field")
          self.details = payload.get("details")
          self.scope = response.headers.get("X-RateLimit-Scope")
          self.retry_after = response.headers.get("Retry-After")
          self.reset = response.headers.get("X-RateLimit-Reset")

  def cotizave(path, *, method="GET", body=None):
      key = os.environ.get("COTIZAVE_API_KEY", "").strip()
      if not key:
          raise ValueError("Set COTIZAVE_API_KEY on the server")
      if not path.startswith("/v1/"):
          raise ValueError("Invalid Cotizave API path")
      with requests.request(
          method, "https://api.cotizave.com" + path,
          headers={"X-API-Key": key, "Accept": "application/json"},
          json=body, timeout=(3, 10), allow_redirects=False
      ) as response:
          try:
              data = response.json()
          except ValueError:
              data = None
          if not 200 <= response.status_code < 300 or data is None:
              raise CotizaveError(response, data)
          return data
  ```
</CodeGroup>

El timeout de `requests` limita conexión e inactividad de lectura; no es un plazo total de ejecución. Si tu aplicación tiene un plazo global, aplícalo también en la capa que llama al cliente. En curl configura la clave sin espacios y no añadas `--location`.

Los ejemplos se ejecutan en el servidor. JavaScript y Python usan los clientes del [inicio rápido](/api/quickstart#paso-2); configura allí `COTIZAVE_API_KEY`.

<CodeGroup>
  ```bash curl theme={null}
  curl --fail-with-body --max-time 10 "https://api.cotizave.com/v1/fx/rates/reference" \
    -H "X-API-Key: $COTIZAVE_API_KEY"
  ```

  ```javascript Node.js theme={null}
  import { cotizave } from './cotizave.mjs';

  const data = await cotizave('/v1/fx/rates/reference');
  console.log(data);
  ```

  ```python Python theme={null}
  from cotizave import cotizave

  data = cotizave('/v1/fx/rates/reference')
  print(data)
  ```
</CodeGroup>

<span id="paso-3" />

## Interpreta la respuesta

Respuesta ilustrativa: las cifras y fechas no son cotizaciones actuales.

```json theme={null}
{
  "market": "reference",
  "type": "reference",
  "mid": 475.0083,
  "updated_at": "2026-10-19T04:00:00Z",
  "effective_date": "2026-10-19"
}
```

`mid` expresa VES por USD en `reference`. `eur_reference` expresa VES por EUR. `updated_at` indica la fecha de actualización y `effective_date` la fecha valor del BCV. No son intercambiables. La fecha valor puede seguir vigente durante varios días no hábiles.

<span id="paso-4" />

## Conecta tu aplicación

Tu backend consulta Cotizave y expone un endpoint propio con los campos que necesita la interfaz. El navegador llama a ese endpoint, sin recibir la API Key. Para uso repetido, comparte una caché entre usuarios y decide cuánto tiempo puedes mostrar un dato antiguo. Consulta [cuotas y límites](/api/rate-limits) antes de programar actualizaciones.

```javascript theme={null}
// Server-side example; use the client saved above.
import { cotizave } from './cotizave.mjs';
const snapshot = await cotizave('/v1/fx/rates');
const rate = snapshot.rates.find(item => item.market === 'reference');
if (!rate) throw new Error('BCV rate unavailable');
console.log({ rate: rate.mid, effective_date: rate.effective_date });
```

<span id="proximos" />

## Próximos pasos

Consulta [autenticación](/api/authentication), [conversión](/api/endpoints/convert), [histórico](/api/endpoints/history) y [webhooks](/guides/webhooks).

<span id="tips" />

## Errores y frescura

No reintentes errores de parámetros, credenciales o plan. Para `429`, distingue `burst` de `monthly` y respeta las cabeceras. Limita los reintentos de GET ante fallos transitorios; no repitas automáticamente un POST cuyo resultado sea incierto. Una respuesta HTTP correcta no garantiza que cada fuente sea reciente.

<span id="problemas" />

## Resolver problemas

Además pueden producirse los [errores comunes](/api/errors) de autenticación, cuota o disponibilidad. Las respuestas de error de la API son JSON; decide por `code`, no por el texto de `message`.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.