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

# Codigos de error API Camtom | Referencia

> Referencia de errores HTTP de la API Camtom: 400, 401, 402, 403, 422, 429, 500 y 502. Causas y soluciones con ejemplos de codigo.

La API de Camtom usa codigos HTTP estandar. Los errores devuelven un objeto JSON con el tipo de error, un mensaje descriptivo y el codigo de estado.

## Formato de error

Todas las respuestas de error de la API siguen esta estructura:

```json theme={null}
{
  "error": "InvalidRequest",
  "message": "El campo 'product_description' es requerido.",
  "status_code": 400
}
```

<ResponseField name="error" type="string">
  Nombre del tipo de error. Corresponde al nombre de la clase de excepcion interna (ej. `InvalidRequest`, `InvalidEncoding`, `InternalServerError`).
</ResponseField>

<ResponseField name="message" type="string">
  Descripcion legible del error. Util para debugging y logs.
</ResponseField>

<ResponseField name="status_code" type="number">
  Codigo de estado HTTP del error.
</ResponseField>

## Referencia de codigos

### Errores del cliente (4xx)

| HTTP  | Tipo de error               | Descripcion                         | Causa comun                                                           |
| ----- | --------------------------- | ----------------------------------- | --------------------------------------------------------------------- |
| `400` | `InvalidEncoding`           | Codificacion de caracteres invalida | El request contiene caracteres con codificacion no valida             |
| `400` | `CamtomDocsResourceError`   | Error de archivo o recurso          | Archivo corrupto, no legible o URL no accesible                       |
| `401` | `Unauthorized`              | Autenticacion fallida               | API key ausente, invalida, revocada o expirada                        |
| `402` | `CamtomDocsCreditError`     | Creditos insuficientes              | No hay creditos suficientes para procesar el documento                |
| `403` | `Forbidden`                 | Acceso denegado                     | Suscripcion no valida, expirada, o pais no permitido en plan free     |
| `404` | `CamtomDocsNotFoundError`   | Recurso no encontrado               | El documento o recurso solicitado no existe                           |
| `422` | `CamtomDocsValidationError` | Error de validacion                 | JSON Schema invalido, campos requeridos ausentes o formato incorrecto |
| `429` | `CamtomDocsLimitError`      | Limite de cuota excedido            | Se excedio el limite de uso o cuota de la suscripcion                 |

### Errores del servidor (5xx)

| HTTP  | Tipo de error               | Descripcion                  | Que hacer                                                                           |
| ----- | --------------------------- | ---------------------------- | ----------------------------------------------------------------------------------- |
| `500` | `InternalServerError`       | Error interno del servidor   | Reintentar con backoff exponencial. Si persiste, contactar soporte                  |
| `502` | `CamtomDocsProcessingError` | Error en procesamiento de IA | El modelo de IA no pudo procesar el documento. Reintentar o simplificar la peticion |

### Errores de validacion (422) - Detalle

Los errores de validacion de CamtomDocs incluyen un campo `errors` adicional con detalles por campo:

```json theme={null}
{
  "error": "CamtomDocsValidationError",
  "errors": [
    "El campo 'json_response' no puede estar vacio",
    "El campo 'document_type' es requerido"
  ]
}
```

## Manejo de errores

### Patron recomendado

<CodeGroup>
  ```python Python theme={null}
  import requests
  import time

  def call_camtom_api(url, headers, data, files=None, params=None, max_retries=3):
      for attempt in range(max_retries):
          response = requests.post(url, headers=headers, data=data, files=files, params=params)

          if response.status_code == 200:
              return response.json()

          error_body = response.json()
          error_type = error_body.get("error", "Unknown")
          message = error_body.get("message", "Error desconocido")

          # Errores que no se resuelven reintentando
          if response.status_code in (400, 401, 402, 403, 404, 422):
              raise Exception(f"Error {response.status_code} ({error_type}): {message}")

          # Limite de cuota: esperar antes de reintentar
          if response.status_code == 429:
              wait_time = 2 ** attempt
              print(f"Limite excedido. Reintentando en {wait_time}s...")
              time.sleep(wait_time)
              continue

          # Error del servidor: reintentar con backoff exponencial
          if response.status_code >= 500:
              wait_time = 2 ** attempt
              print(f"Error del servidor ({error_type}). Reintentando en {wait_time}s...")
              time.sleep(wait_time)
              continue

      raise Exception("Maximo de reintentos alcanzado")


  # Ejemplo de uso con TariffPro Mini
  result = call_camtom_api(
      url="https://api.camtomx.com/api/v3/tariffpro/tariffpro-mini",
      headers={"Authorization": "Bearer sk_tu_api_key"},
      params={"country_code": "MEX", "model": "pro"},
      data={"product_description": "Tornillo de acero inoxidable M8x40mm"}
  )
  ```

  ```javascript JavaScript theme={null}
  async function callCamtomAPI(url, headers, formData, params = {}, maxRetries = 3) {
    const queryString = new URLSearchParams(params).toString();
    const fullUrl = queryString ? `${url}?${queryString}` : url;

    for (let attempt = 0; attempt < maxRetries; attempt++) {
      const response = await fetch(fullUrl, {
        method: "POST",
        headers,
        body: formData
      });

      if (response.ok) {
        return await response.json();
      }

      const errorBody = await response.json();
      const { error: errorType, message } = errorBody;

      // Errores que no se resuelven reintentando
      if ([400, 401, 402, 403, 404, 422].includes(response.status)) {
        throw new Error(`Error ${response.status} (${errorType}): ${message}`);
      }

      // Limite de cuota: esperar antes de reintentar
      if (response.status === 429) {
        const waitTime = 2 ** attempt;
        console.log(`Limite excedido. Reintentando en ${waitTime}s...`);
        await new Promise(r => setTimeout(r, waitTime * 1000));
        continue;
      }

      // Error del servidor: backoff exponencial
      if (response.status >= 500) {
        const waitTime = 2 ** attempt;
        console.log(`Error del servidor (${errorType}). Reintentando en ${waitTime}s...`);
        await new Promise(r => setTimeout(r, waitTime * 1000));
        continue;
      }
    }

    throw new Error("Maximo de reintentos alcanzado");
  }

  // Ejemplo de uso con TariffPro Mini
  const formData = new FormData();
  formData.append("product_description", "Tornillo de acero inoxidable M8x40mm");

  const result = await callCamtomAPI(
    "https://api.camtomx.com/api/v3/tariffpro/tariffpro-mini",
    { "Authorization": "Bearer sk_tu_api_key" },
    formData,
    { country_code: "MEX", model: "pro" }
  );
  ```
</CodeGroup>

## Escenarios comunes y soluciones

### API key invalida (401)

```json theme={null}
{
  "error": "Unauthorized",
  "message": "Invalid or expired token",
  "status_code": 401
}
```

**Solucion:** Verifica que el header `Authorization` tenga el formato `Bearer sk_...` y que la key no haya sido revocada. Genera una nueva key desde [app.camtomx.com](https://app.camtomx.com) si es necesario.

### Suscripcion no valida (403)

```json theme={null}
{
  "error": "Forbidden",
  "message": "Organization subscription is not active or not pro/enterprise",
  "status_code": 403
}
```

**Solucion:** Verifica que tu organizacion tenga una suscripcion `pro` o `enterprise` activa. Las API keys requieren uno de estos planes.

### Pais no permitido (403)

```json theme={null}
{
  "error": "Forbidden",
  "message": "Your current plan only allows access to WORLD classifications.",
  "status_code": 403
}
```

**Solucion:** Las organizaciones con plan `free` solo pueden usar `country_code=WORLD`. Actualiza a plan `pro` para acceder a clasificaciones por pais.

### Creditos insuficientes (402)

```json theme={null}
{
  "error": "CamtomDocsCreditError",
  "message": "Insufficient credits",
  "status_code": 402
}
```

**Solucion:** Recarga creditos desde **Settings > Billing** en [app.camtomx.com](https://app.camtomx.com).

### Error de validacion (422)

```json theme={null}
{
  "error": "CamtomDocsValidationError",
  "errors": [
    "json_response cannot be empty"
  ]
}
```

**Solucion:** Revisa que el campo `json_data` contenga un JSON valido con `document_type`, `document_description` y un `json_response` no vacio que cumpla con JSON Schema Draft 7.

### Error de procesamiento (502)

```json theme={null}
{
  "error": "CamtomDocsProcessingError",
  "message": "AI processing failed",
  "status_code": 502
}
```

**Solucion:** Reintenta la peticion. Si el error persiste, verifica que el documento sea legible y que el schema no sea excesivamente complejo.

### Error de codificacion (400)

```json theme={null}
{
  "error": "InvalidEncoding",
  "message": "Invalid character encoding in request",
  "status_code": 400
}
```

**Solucion:** Asegurate de que el request use codificacion UTF-8.

<Info>
  Si recibes errores de forma consistente y no puedes resolverlos, contacta al equipo de soporte en [app.camtomx.com](https://app.camtomx.com) con el tipo de error, el mensaje completo y un ejemplo del request que genera el error.
</Info>
