# Errores

> Versión Markdown de https://docs.preciosgasolina.es/conceptos/errores/ · Actualizado: 2026-10-07 · Índice para LLM: https://docs.preciosgasolina.es/llms.txt

Errores de la API de Gasolina hoy en formato RFC 9457 (problem+json): campos, códigos estables como RATE_LIMITED, estado HTTP y qué hacer.

Cuando una petición falla, la API responde con el estado HTTP adecuado y un cuerpo **`application/problem+json`** según el [RFC 9457](https://www.rfc-editor.org/rfc/rfc9457). Los errores no se cachean (`Cache-Control: no-store`) y llevan la cabecera `X-Request-Id`.

## Formato

Ejemplo ilustrativo

```json
{
  "type": "https://docs.preciosgasolina.es/conceptos/errores/#province-not-found",
  "title": "No encontrado",
  "status": 404,
  "detail": "No existe la provincia 99.",
  "code": "PROVINCE_NOT_FOUND",
  "request_id": "e74dbaec2b574590",
  "instance": "/v1/prices"
}
```

| Campo        | Significado                                                                                     |
| ------------ | ----------------------------------------------------------------------------------------------- |
| `type`       | URL de la explicación del error en esta página (`#` + el código en minúsculas y con guiones).   |
| `title`      | Resumen legible del tipo de error.                                                              |
| `status`     | El mismo estado HTTP de la respuesta.                                                           |
| `detail`     | Explicación concreta de este caso (qué parámetro, qué valor).                                   |
| `code`       | **Código estable** del error. Es el campo que debe comprobar tu código.                         |
| `request_id` | Identificador de la petición (igual que la cabecera `X-Request-Id`). Inclúyelo si nos escribes. |
| `instance`   | Ruta de la petición, cuando se conoce.                                                          |

> **Comprueba el campo code, no el texto**
>
> `title` y `detail` son textos en español que pueden cambiar. `code` y `status` son estables dentro de la versión `v1`.

Solo `429` y `503` llevan `Retry-After`: son los únicos errores que se resuelven esperando. El resto se arreglan cambiando la petición.

## Códigos

| `code`                                                | Estado | Cuándo                                                         |
| ----------------------------------------------------- | ------ | -------------------------------------------------------------- |
| [`INVALID_PARAMETER`](#invalid-parameter)             | 400    | Parámetro desconocido, repetido, mal escrito o fuera de rango. |
| [`INVALID_JSON`](#invalid-json)                       | 400    | El cuerpo de un `POST` no es JSON válido.                      |
| [`*_NOT_FOUND`](#not-found)                           | 404    | La gasolinera, el territorio, la marca… no existe.             |
| [`ENDPOINT_NOT_FOUND`](#endpoint-not-found)           | 404    | La ruta no existe.                                             |
| [`METHOD_NOT_ALLOWED`](#method-not-allowed)           | 405    | Método HTTP no admitido.                                       |
| [`PAYLOAD_TOO_LARGE`](#payload-too-large)             | 413    | Cuerpo de más de 32 KB.                                        |
| [`URI_TOO_LONG`](#uri-too-long)                       | 414    | URL de más de 2.048 caracteres.                                |
| [`UNSUPPORTED_MEDIA_TYPE`](#unsupported-media-type)   | 415    | `POST` sin `Content-Type: application/json`.                   |
| [`RATE_LIMITED`](#rate-limited)                       | 429    | Has superado un límite por IP.                                 |
| [`INTERNAL_ERROR`](#internal-error)                   | 500    | Error inesperado.                                              |
| [`ENDPOINT_DISABLED`](#endpoint-disabled)             | 503    | Endpoint desactivado temporalmente.                            |
| [`TEMPORARILY_UNAVAILABLE`](#temporarily-unavailable) | 503    | Los datos no están disponibles en este momento.                |

### INVALID_PARAMETER (400)

Un parámetro no es válido. `detail` dice cuál y por qué. Causas habituales:

- Un parámetro que el endpoint no admite (`parámetros no admitidos: …`): la API es estricta y no ignora parámetros desconocidos.
- Un parámetro repetido (`?fuel=diesel&fuel=lpg`).
- Un valor que no está en la lista (`fuel=petrol`) o fuera de rango (`limit=500`, `radius_km=80`, coordenadas fuera de España).
- Una combinación incompleta: `lat` sin `lng`, `level=province` sin `code`, municipios sin `parent` en `/v1/territories`, una ruta propia de más de 1.500 km, el informe de un mes que aún no ha terminado.

**Qué hacer:** corrige la petición; no reintentes.

### INVALID_JSON (400)

El cuerpo de `POST /v1/route/fuel` no se puede leer como JSON. Comprueba que envías un JSON válido (por ejemplo, con `JSON.stringify`).

### Recursos no encontrados (404)

Lo que pides no existe. El prefijo dice qué:

- `STATION_NOT_FOUND`: la gasolinera no existe o ya no vende al público.
- `COMMUNITY_NOT_FOUND`: no existe esa comunidad autónoma (código INE o slug).
- `PROVINCE_NOT_FOUND`: no existe esa provincia.
- `MUNICIPALITY_NOT_FOUND`: no existe ese municipio. Usa el id de `/v1/search` o `/v1/territories`, no el código INE.
- `BRAND_NOT_FOUND`: no existe esa marca (lista en `/v1/brands`).
- `PRODUCT_NOT_FOUND`: producto desconocido.
- `ROAD_NOT_FOUND`: no hay datos de esa carretera (lista en `/v1/roads`).
- `REPORT_NOT_FOUND`: no hay datos de ese mes.
- `GUIDE_NOT_FOUND`, `ARTICLE_NOT_FOUND` y `ROUTE_NOT_FOUND`: no existe esa guía, artículo del blog o ruta (busca en `/v1/content` o `/v1/routes`).

**Qué hacer:** comprueba el identificador con el endpoint de búsqueda o de lista correspondiente.

### ENDPOINT_NOT_FOUND (404)

La ruta no existe. Revisa la [referencia](https://docs.preciosgasolina.es/referencia/): todas las rutas empiezan por `/v1/` y terminan sin extensión.

### METHOD_NOT_ALLOWED (405)

La API es de solo lectura: admite `GET`, `HEAD` y `OPTIONS`, y `POST` solo en `/v1/route/fuel`. La respuesta lleva la cabecera `Allow`.

### PAYLOAD_TOO_LARGE (413)

El cuerpo de `POST /v1/route/fuel` pasa de 32 KB. Envía menos puntos (como mucho 200). En el servidor MCP, un mensaje de más de 64 KB se rechaza con `413` y un error JSON-RPC.

### URI_TOO_LONG (414)

La URL pasa de 2.048 caracteres. Si necesitas enviar muchos puntos, usa `POST /v1/route/fuel`.

### UNSUPPORTED_MEDIA_TYPE (415)

Un `POST` sin `Content-Type: application/json`. Añade la cabecera.

### RATE_LIMITED (429)

Has superado un límite por IP: 120 peticiones por minuto (o 20 cada 10 segundos) o 30 consultas pesadas por minuto. La respuesta lleva `Retry-After` (segundos) y `RateLimit-Policy`.

**Qué hacer:** espera lo que indique `Retry-After` y cachea las respuestas hasta `meta.next_update`. Ver [Límites de uso](https://docs.preciosgasolina.es/conceptos/limites/).

### INTERNAL_ERROR (500)

Error inesperado de la API. Puedes reintentar una vez pasados unos segundos; si se repite, escríbenos a <hola@preciosgasolina.es> con el `request_id`.

### ENDPOINT_DISABLED (503)

El endpoint (o toda la API) está desactivado temporalmente, por ejemplo por mantenimiento. Lleva `Retry-After: 3600`.

### TEMPORARILY_UNAVAILABLE (503)

La fuente de datos no responde, se ha alcanzado el presupuesto mensual de la API o no se pudo calcular la respuesta, y no hay una copia anterior que servir. Lleva `Retry-After` (normalmente 60 segundos).

**Qué hacer:** espera y reintenta; mientras tanto, muestra los últimos datos que tengas con su fecha. Ver [Frescura de los datos](https://docs.preciosgasolina.es/conceptos/frescura/).

## Errores del servidor MCP

El servidor MCP usa errores JSON-RPC para los problemas de transporte (`429` con `Retry-After`, mensaje de más de 64 KB, JSON no válido, lotes no admitidos, método `GET`) y, dentro de una llamada a herramienta, un resultado con `isError: true` cuyo texto empieza por el mismo `code` de esta página (por ejemplo, `STATION_NOT_FOUND: No existe la gasolinera …`).
