This is the full developer documentation for Gasolina hoy (preciosgasolina.es) · API y MCP # Precios de carburantes de España para tus apps y agentes de IA > Una API REST y un servidor MCP gratuitos, sin clave y de solo lectura con los precios oficiales de unas 11.500 gasolineras, del Ministerio para la Transición Ecológica y el Reto Demográfico. **Gasolina hoy** ([preciosgasolina.es](https://preciosgasolina.es/)) publica los precios que las gasolineras comunican al Ministerio para la Transición Ecológica y el Reto Demográfico. Esta documentación explica cómo usarlos desde tu código con la **API REST** (`https://api.preciosgasolina.es/v1`) o desde un asistente de IA con el **servidor MCP** (`https://mcp.preciosgasolina.es/mcp`). * **Gratis**sin registro ni clave de API * **Solo lectura**GET (y un POST para rutas propias) * **2 veces al día**hacia las 8:00 y las 20:00, hora peninsular * **CC BY 4.0**con atribución a Gasolina hoy y al Ministerio * **\~11.500**gasolineras de venta al público ## Qué puedes hacer [Sección titulada «Qué puedes hacer»](#qué-puedes-hacer) API REST 30 endpoints en JSON: precio medio por territorio, gasolineras más baratas y cercanas, ficha de cada gasolinera, histórico de 90 días, carreteras, rutas, contenido y calculadoras. Sobre `{ data, meta }` y errores RFC 9457. [Referencia de la API](/referencia/) Servidor MCP 21 herramientas de solo lectura para agentes de IA, con transporte Streamable HTTP, sin estado y sin inicio de sesión. Funciona en Claude, ChatGPT, Cursor, VS Code y Claude Code. [Herramientas del MCP](/mcp/herramientas/) Asistentes de IA ¿No programas? Añade el conector en Claude o ChatGPT y pregunta por el diésel más barato de tu provincia o por el coste de un viaje, con datos oficiales. [Cómo se conecta](/mcp/conectar/) Datos abiertos ¿Necesitas todas las gasolineras o series completas? Descarga las medias diarias de 90 días y todas las gasolineras con los precios de hoy en CSV y JSON, con la misma licencia. [Descargar los datos](https://preciosgasolina.es/datos/) ## Por dónde empezar [Sección titulada «Por dónde empezar»](#por-dónde-empezar) [Primeros pasos](/empezar/primeros-pasos/)Tu primera petición con curl, cómo leer la respuesta y tu primera conexión MCP. [Conceptos básicos](/empezar/conceptos-basicos/)Carburantes, niveles territoriales, códigos INE y cómo obtener cada identificador. [Gasolinera más barata cerca](/guias/gasolinera-mas-barata-cerca/)Guía completa con curl, JavaScript y Python. [Atribución y licencia](/empezar/atribucion-y-licencia/)Qué texto mostrar junto a los datos y cómo enlazar la fuente. [Límites de uso](/conceptos/limites/)Peticiones por minuto, topes de parámetros y cómo reintentar. [Frescura de los datos](/conceptos/frescura/)Cuándo se actualizan los precios y cómo saber su antigüedad. ## Para agentes y LLM [Sección titulada «Para agentes y LLM»](#para-agentes-y-llm) Cada página tiene una versión en Markdown en `/index.md` (por ejemplo, [/empezar/primeros-pasos/index.md](/empezar/primeros-pasos/index.md)). El índice para modelos de lenguaje está en [/llms.txt](/llms.txt), la documentación completa en [/llms-full.txt](/llms-full.txt) y la especificación de la API en [openapi.json](https://api.preciosgasolina.es/v1/openapi.json) (OpenAPI 3.1). # Atribución y licencia > Los datos de la API y del MCP de Gasolina hoy tienen licencia CC BY 4.0. Qué texto de atribución mostrar, dónde ponerlo y cómo enlazar la fuente. Puedes usar, copiar, transformar y publicar los datos de la API REST y del servidor MCP, también con fines comerciales, con una condición: **citar la fuente**. Los datos se publican con la licencia [Creative Commons Atribución 4.0 Internacional (CC BY 4.0)](https://creativecommons.org/licenses/by/4.0/deed.es), la misma que las [descargas de datos abiertos](https://preciosgasolina.es/datos/) de la web. ## Texto de atribución [Sección titulada «Texto de atribución»](#texto-de-atribución) Cada respuesta incluye el texto exacto en `meta.attribution`: ```text Fuente: Gasolina hoy (preciosgasolina.es), con datos del Ministerio para la Transición Ecológica y el Reto Demográfico (Geoportal de Gasolineras). ``` Muéstralo **cerca de los datos** (debajo de la tabla, del mapa o del widget), de forma legible, y lee siempre el texto de `meta.attribution` en lugar de copiarlo a mano: si algún día cambia, tu aplicación lo mostrará actualizado. ## Enlaza la fuente [Sección titulada «Enlaza la fuente»](#enlaza-la-fuente) Cada respuesta trae también `meta.web_url`: la página de preciosgasolina.es que muestra esos mismos datos (la provincia, la gasolinera, la carretera…). Enlázala desde el texto de atribución o desde un «Ver en preciosgasolina.es». Así tus usuarios pueden comprobar el dato y ver más detalle. Las gasolineras llevan además su propio `web_url` (su ficha en la web) y los territorios, el de su página. * HTML ```html

Fuente: Gasolina hoy (preciosgasolina.es), con datos del Ministerio para la Transición Ecológica y el Reto Demográfico (Geoportal de Gasolineras). Datos del 7 de octubre de 2026, 8:12. Licencia CC BY 4.0.

``` * JavaScript ```js // meta = respuesta.meta de cualquier endpoint function atribucion(meta) { const p = document.createElement("p"); const a = document.createElement("a"); a.href = meta.web_url ?? "https://preciosgasolina.es/"; a.textContent = "Ver en preciosgasolina.es"; const fecha = new Date(meta.last_updated).toLocaleString("es-ES", { timeZone: "Europe/Madrid", dateStyle: "long", timeStyle: "short" }); p.append(meta.attribution + " Datos de " + fecha + ". Licencia CC BY 4.0. ", a); return p; } ``` * Python ```python from datetime import datetime from zoneinfo import ZoneInfo def atribucion(meta: dict) -> str: fecha = datetime.fromisoformat(meta["last_updated"].replace("Z", "+00:00")).astimezone(ZoneInfo("Europe/Madrid")) return f'{meta["attribution"]} Datos de {fecha:%d/%m/%Y %H:%M}. Licencia CC BY 4.0. {meta["web_url"]}' ``` ## Muestra la fecha de los datos [Sección titulada «Muestra la fecha de los datos»](#muestra-la-fecha-de-los-datos) Los precios no son en tiempo real: se actualizan dos veces al día. Junto a la atribución, muestra la fecha y hora de `meta.last_updated` (en hora de Madrid) para que nadie confunda un precio de por la mañana con el del surtidor por la tarde. Ver [Frescura de los datos](/conceptos/frescura/). ## En asistentes y agentes de IA [Sección titulada «En asistentes y agentes de IA»](#en-asistentes-y-agentes-de-ia) Los resultados del servidor MCP llevan el mismo `meta` (en `structuredContent`). Si construyes un agente, haz que cite la fuente y enlace `web_url` en sus respuestas; las [buenas prácticas del MCP](/mcp/buenas-practicas/) lo explican. ## Qué no cubre la licencia [Sección titulada «Qué no cubre la licencia»](#qué-no-cubre-la-licencia) Precaución * La licencia cubre los **datos** (precios, medias, listados). No da derechos sobre la marca Gasolina hoy, su logotipo ni el diseño de la web; tampoco sobre las marcas de las gasolineras. * Las **fotos** de las rutas tienen su propia licencia y autor, que vienen en cada foto (`credit`): respétalos si las muestras. * Si reutilizas textos de guías, artículos o rutas (`/v1/content`), cita su autoría (Gasolina hoy) y enlaza su `web_url`. Las condiciones completas de uso del servicio están en los [términos de uso](/terminos/). # Conceptos básicos > Identificadores de la API de Gasolina hoy: carburantes, productos, niveles territoriales, códigos INE, municipios, gasolineras y slugs, y cómo obtenerlos. La API y el servidor MCP usan identificadores estables para los carburantes, los territorios, las gasolineras, las marcas, las carreteras y las rutas. Esta página explica cada uno y cómo obtenerlo con `/v1/search` y `/v1/territories`. ## Carburantes [Sección titulada «Carburantes»](#carburantes) El parámetro `fuel` acepta seis identificadores: | `fuel` | Carburante | Unidad del precio | | ---------------- | ---------------------------- | ----------------- | | `gasoline_95` | Gasolina 95 E5 | €/L | | `gasoline_98` | Gasolina 98 E5 | €/L | | `diesel` | Gasóleo A (diésel) | €/L | | `diesel_premium` | Gasóleo premium | €/L | | `lpg` | GLP (autogás) | €/L | | `cng` | GNC (gas natural comprimido) | €/kg | Cada respuesta indica la unidad en `unit` (`L` o `kg`) y la moneda en `currency` (`EUR`). ## Productos [Sección titulada «Productos»](#productos) Además de los seis carburantes, el Ministerio publica otros productos que solo comunican algunas gasolineras. Se consultan con `GET /v1/products/{id}` (o la herramienta MCP `get_product_prices`): | `id` | Producto | | ----------------- | ------------------------- | | `adblue` | AdBlue | | `diesel_b` | Gasóleo B (agrícola) | | `hvo` | HVO (diésel renovable) | | `lng` | GNL (gas natural licuado) | | `gasoline_95_e10` | Gasolina 95 E10 | | `gasoline_98_e10` | Gasolina 98 E10 | Los datos de productos solo cubren las gasolineras que comunican su precio al Ministerio, no todas las que los venden. ## Niveles territoriales y códigos [Sección titulada «Niveles territoriales y códigos»](#niveles-territoriales-y-códigos) Muchos endpoints aceptan un territorio con dos parámetros: `level` y `code`. | `level` | `code` | Ejemplo | | -------------- | -------------------------------------------------------- | -------------------------------------------------------- | | `spain` | no hace falta | España entera (es el valor por defecto) | | `community` | código INE de la comunidad autónoma (2 cifras) o su slug | `13` o `comunidad-de-madrid` | | `province` | código INE de la provincia (2 cifras) o su slug | `28` o `madrid` | | `municipality` | id de municipio de la API | el `code` que devuelven `/v1/search` o `/v1/territories` | Los códigos INE de comunidades y provincias son los oficiales del Instituto Nacional de Estadística (`28` = Madrid, `46` = Valencia, `08` = Barcelona…). Puedes escribirlos con o sin cero a la izquierda (`8` o `08`). Municipios: usa el id de la API El `code` de un municipio **no es su código INE**: es el identificador interno que devuelven `/v1/search` (campo `code` de los resultados de tipo municipio) y `/v1/territories?level=municipality&parent=`. Búscalo siempre con uno de esos dos endpoints. ### Canarias, Ceuta y Melilla [Sección titulada «Canarias, Ceuta y Melilla»](#canarias-ceuta-y-melilla) Canarias, Ceuta y Melilla no pagan el Impuesto sobre Hidrocarburos, así que sus precios no son comparables con los del resto de España. En los rankings nacionales de «más baratas» (`/v1/stations/cheapest` sin territorio y `/v1/rankings/regions`) van aparte salvo que pidas `include_low_tax=true`. Las gasolineras y comunidades de esas zonas llevan `low_tax_area: true`. ## Gasolineras [Sección titulada «Gasolineras»](#gasolineras) Cada gasolinera tiene: * **`id`**: el identificador del Ministerio (IDEESS), un número entero. Es estable. * **Slug**: la última parte de su `web_url` (`https://preciosgasolina.es/gasolineras//`). `GET /v1/stations/{id}` y `GET /v1/stations/{id}/history` aceptan cualquiera de los dos. ## Marcas, carreteras y rutas [Sección titulada «Marcas, carreteras y rutas»](#marcas-carreteras-y-rutas) * **Marcas**: slug en minúsculas con guiones (`repsol`, `ballenoil`…). Lista completa en `GET /v1/brands`. * **Carreteras**: slug del código de la carretera en minúsculas (`a-3`, `ap-7`, `n-340`). Lista en `GET /v1/roads`. * **Rutas del catálogo**: slug de la ruta de preciosgasolina.es. Búscalas con `GET /v1/routes`. * **Contenido**: `type` (`guide`, `post` o `route`) + slug. Búscalo con `GET /v1/content`. ## Cómo obtener los identificadores [Sección titulada «Cómo obtener los identificadores»](#cómo-obtener-los-identificadores) ### Desde un texto: `/v1/search` [Sección titulada «Desde un texto: /v1/search»](#desde-un-texto-v1search) Convierte un nombre, un código postal o una gasolinera en identificadores. Acepta `q` (de 2 a 100 caracteres) y `limit` (1–20, por defecto 8). * curl ```sh curl "https://api.preciosgasolina.es/v1/search?q=getafe" ``` * JavaScript ```js const res = await fetch("https://api.preciosgasolina.es/v1/search?q=" + encodeURIComponent("getafe")); const { data } = await res.json(); const municipio = data.results.find((r) => r.type === "municipality"); console.log(municipio.level, municipio.code); // → "municipality", "" ``` * Python ```python import requests data = requests.get("https://api.preciosgasolina.es/v1/search", params={"q": "getafe"}, timeout=10).json()["data"] municipio = next(r for r in data["results"] if r["type"] == "municipality") print(municipio["level"], municipio["code"]) ``` Ejemplo ilustrativo: los valores no son reales ```json { "data": { "query": "getafe", "results": [ { "type": "municipality", "name": "Getafe", "detail": "Madrid", "web_url": "https://preciosgasolina.es/precios-gasolineras/comunidad-de-madrid/madrid/getafe/", "level": "municipality", "code": "4300" }, { "type": "station", "name": "Estación de ejemplo", "detail": "Madrid", "web_url": "https://preciosgasolina.es/gasolineras/estacion-de-ejemplo-12345/", "station_id": 12345, "address": "Calle de Ejemplo, 1", "brand_slug": "marca-ejemplo" } ] }, "meta": { "…": "…" } } ``` Cada resultado tiene un `type`: `community`, `province`, `municipality`, `postal_code` o `station`. Los territorios traen `level` y `code` (listos para usar en `level` + `code`) y las gasolineras, `station_id`. ### Desde la lista: `/v1/territories` [Sección titulada «Desde la lista: /v1/territories»](#desde-la-lista-v1territories) Devuelve los territorios con sus identificadores: | Petición | Devuelve | | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | | `GET /v1/territories` | Comunidades autónomas (`code`, `slug`, `name`, códigos de sus provincias, `low_tax_area`) | | `GET /v1/territories?level=province` | Provincias (`code`, `slug`, `name`, `community_code`). Con `parent=`, solo las de esa comunidad | | `GET /v1/territories?level=municipality&parent=28` | Municipios de una provincia (`code`, `slug`, `name`, códigos postales, número de gasolineras y coordenadas). `parent` es obligatorio | En el servidor MCP, la herramienta `search_places` hace lo mismo que `/v1/search` y el recurso `fuel://territories` lista comunidades y provincias con sus códigos INE. ## Coordenadas [Sección titulada «Coordenadas»](#coordenadas) Las coordenadas son WGS84 en grados decimales (`lat`, `lng`) y deben estar dentro de España, Canarias incluidas (latitud de 27,4 a 44, longitud de −18,4 a 4,6). La API las **redondea a 3 decimales** (unos 100 m) antes de usarlas: las respuestas son idénticas para puntos cercanos y no identifican a nadie. # Primeros pasos > Haz tu primera petición a la API de Gasolina hoy con curl, lee el sobre de respuesta y conecta el servidor MCP a tu asistente en 5 minutos. En este tutorial harás tu primera petición a la API REST, entenderás qué devuelve y conectarás el servidor MCP a un asistente de IA. No necesitas registrarte ni pedir una clave: la API y el MCP son gratuitos y de solo lectura. **Necesitas:** una terminal con `curl` (o Node.js 18+ o Python 3) y, para la segunda parte, un cliente MCP como Claude, ChatGPT, Cursor, VS Code o Claude Code. ## 1. Tu primera petición [Sección titulada «1. Tu primera petición»](#1-tu-primera-petición) La API está en `https://api.preciosgasolina.es/v1`. Pide las 5 gasolineras con el diésel más barato de la provincia de Madrid (código INE `28`): * curl ```sh curl "https://api.preciosgasolina.es/v1/stations/cheapest?fuel=diesel&level=province&code=28&limit=5" ``` * JavaScript ```js const url = new URL("https://api.preciosgasolina.es/v1/stations/cheapest"); url.search = new URLSearchParams({ fuel: "diesel", level: "province", code: "28", limit: "5" }); const res = await fetch(url); const { data, meta } = await res.json(); console.log(data.stations.map((s) => `${s.price} €/L · ${s.name} (${s.municipality.name})`)); console.log("Datos de", meta.last_updated, "·", meta.attribution); ``` * Python ```python import requests # pip install requests r = requests.get( "https://api.preciosgasolina.es/v1/stations/cheapest", params={"fuel": "diesel", "level": "province", "code": "28", "limit": 5}, timeout=10, ) r.raise_for_status() body = r.json() for s in body["data"]["stations"]: print(s["price"], "€/L ·", s["name"], f'({s["municipality"]["name"]})') print("Datos de", body["meta"]["last_updated"], "·", body["meta"]["attribution"]) ``` ## 2. Lee la respuesta [Sección titulada «2. Lee la respuesta»](#2-lee-la-respuesta) Todas las respuestas correctas tienen la misma forma: un objeto con `data` (el resultado) y `meta` (fecha, fuente, licencia y enlace a la web). Así es una respuesta recortada a una gasolinera: Ejemplo ilustrativo: los valores no son precios reales ```json { "data": { "fuel": "diesel", "unit": "L", "currency": "EUR", "area": { "level": "province", "code": "28", "name": "Madrid", "web_url": "https://preciosgasolina.es/precios-gasolineras/comunidad-de-madrid/madrid/" }, "note": null, "stations": [ { "id": 12345, "name": "Estación de ejemplo", "brand": { "slug": "marca-ejemplo", "name": "Marca Ejemplo" }, "address": "Calle de Ejemplo, 1", "postal_code": "28001", "municipality": { "id": 4354, "name": "Madrid" }, "province": { "code": "28", "name": "Madrid" }, "community": { "code": "13", "name": "Comunidad de Madrid" }, "lat": 40.39, "lng": -3.65, "is_24h": true, "hours": "L-D: 24H", "low_tax_area": false, "web_url": "https://preciosgasolina.es/gasolineras/estacion-de-ejemplo-12345/", "price": 1.459, "price_updated_at": "2026-10-07T06:12:00.000+00:00" } ] }, "meta": { "api_version": "v1", "request_id": "8c1f2a9b3d4e5f60", "last_updated": "2026-10-07T06:12:00.000Z", "next_update": "2026-10-07T18:10:00.000Z", "data_age_seconds": 7430, "stale": false, "source": "Ministerio para la Transición Ecológica y el Reto Demográfico (Geoportal de Gasolineras)", "attribution": "Fuente: Gasolina hoy (preciosgasolina.es), con datos del Ministerio para la Transición Ecológica y el Reto Demográfico (Geoportal de Gasolineras).", "license": "https://creativecommons.org/licenses/by/4.0/", "web_url": "https://preciosgasolina.es/precios-gasolineras/comunidad-de-madrid/madrid/" } } ``` Fíjate en tres campos de `meta`: * **`last_updated`**: fecha y hora (UTC) de los datos. Los precios se actualizan dos veces al día, hacia las 8:00 y las 20:00 (hora peninsular): **no son en tiempo real**. Más en [Frescura de los datos](/conceptos/frescura/). * **`attribution`**: el texto que debes mostrar junto a los datos (licencia CC BY 4.0). Más en [Atribución y licencia](/empezar/atribucion-y-licencia/). * **`web_url`**: la página equivalente de preciosgasolina.es, para enlazarla como fuente. Los precios van en euros por litro (por kilo con el GNC) y con tres decimales, como los publica el Ministerio. Cada campo está explicado en la [referencia](/referencia/). ## 3. Prueba un error [Sección titulada «3. Prueba un error»](#3-prueba-un-error) Pide un carburante que no existe: ```sh curl -i "https://api.preciosgasolina.es/v1/prices?fuel=petrol" ``` La API responde `400` con un error en formato RFC 9457 (`application/problem+json`) y un `code` estable que tu código puede comprobar: Ejemplo ilustrativo ```json { "type": "https://docs.preciosgasolina.es/conceptos/errores/#invalid-parameter", "title": "Parámetros no válidos", "status": 400, "detail": "fuel: Invalid option: expected one of \"gasoline_95\"|\"gasoline_98\"|\"diesel\"|\"diesel_premium\"|\"lpg\"|\"cng\"", "code": "INVALID_PARAMETER", "request_id": "c51fe0c34cbb42eb", "instance": "/v1/prices" } ``` La lista de códigos está en [Errores](/conceptos/errores/). ## 4. Conecta el servidor MCP [Sección titulada «4. Conecta el servidor MCP»](#4-conecta-el-servidor-mcp) El servidor MCP ofrece los mismos datos a los asistentes de IA. Su dirección es: ```text https://mcp.preciosgasolina.es/mcp ``` No hace falta iniciar sesión. Por ejemplo, en Claude Code: ```sh claude mcp add --transport http preciosgasolina https://mcp.preciosgasolina.es/mcp ``` 1. Añade el servidor en tu cliente (pasos para Claude, ChatGPT, Cursor y VS Code en [Conectar el servidor MCP](/mcp/conectar/)). 2. Abre un chat nuevo y activa el conector si tu cliente lo pide. 3. Pregunta, por ejemplo: «¿Qué provincia tiene el diésel más barato hoy?». El asistente usará la herramienta `compare_regions` y te dará la fecha de los datos y el enlace a preciosgasolina.es. Antes de ir a producción Lee los [límites de uso](/conceptos/limites/) (120 peticiones por minuto por IP en la API REST) y cómo [cachear hasta la próxima actualización](/guias/integrar-en-tu-web/) con `meta.next_update`: los datos solo cambian dos veces al día. ## Siguientes pasos [Sección titulada «Siguientes pasos»](#siguientes-pasos) [Conceptos básicos](/empezar/conceptos-basicos/)Identificadores de carburantes, territorios y gasolineras. [Guías](/guias/gasolinera-mas-barata-cerca/)Casos de uso completos, paso a paso. [Herramientas del MCP](/mcp/herramientas/)Las 21 herramientas con sus argumentos. [Referencia de la API](/referencia/)Endpoints, parámetros y cabeceras. # Referencia de la API REST > URL base, sobre { data, meta }, campos de meta, errores RFC 9457, límites, cabeceras de caché y lista de los 30 endpoints de la API de Gasolina hoy. La API REST de Gasolina hoy es **de solo lectura, gratuita y sin clave**. Devuelve JSON con los precios oficiales de los carburantes de unas 11.500 gasolineras de España y otros datos derivados (histórico, rankings, carreteras, rutas, contenido y calculadoras). | | | | -------------- | -------------------------------------------------------------------------------------------------------------------------------------------- | | URL base | `https://api.preciosgasolina.es/v1` | | Especificación | [OpenAPI 3.1](https://api.preciosgasolina.es/v1/openapi.json) (`application/vnd.oai.openapi+json`) · [Referencia generada](/referencia/api/) | | Formato | JSON UTF-8; errores en `application/problem+json` (RFC 9457) | | Métodos | `GET` y `HEAD` (y `OPTIONS` para CORS); `POST` solo en `/v1/route/fuel` | | Autenticación | Ninguna | | CORS | Cualquier origen (`Access-Control-Allow-Origin: *`), sin credenciales | | Versión | `v1` (en la ruta y en `meta.api_version`) | `GET https://api.preciosgasolina.es/` devuelve un índice con la lista de endpoints, la URL del OpenAPI, la del MCP y la de esta documentación. ## Sobre de respuesta [Sección titulada «Sobre de respuesta»](#sobre-de-respuesta) Toda respuesta correcta es un objeto `{ "data": …, "meta": { … } }`. `data` cambia según el endpoint (sus campos están en la [referencia generada](/referencia/api/)); `meta` es siempre igual: | Campo | Tipo | Significado | | ----------------------- | ----------------------- | ---------------------------------------------------------------------------------------------------------------------- | | `meta.api_version` | texto | Versión de la API que ha respondido (`v1`). | | `meta.request_id` | texto | Identificador de la petición (también en la cabecera `X-Request-Id`). Inclúyelo si nos escribes por un error. | | `meta.last_updated` | texto ISO 8601 o `null` | Fecha y hora (UTC) de la última actualización de los datos. | | `meta.next_update` | texto ISO 8601 | Fecha y hora prevista de la próxima actualización. | | `meta.data_age_seconds` | entero o `null` | Antigüedad de los datos, en segundos. | | `meta.stale` | booleano | `true` si la fuente no respondió y se sirve la última copia buena (los datos pueden ser de la actualización anterior). | | `meta.source` | texto | Fuente de los precios: Ministerio para la Transición Ecológica y el Reto Demográfico (Geoportal de Gasolineras). | | `meta.attribution` | texto | Texto de atribución que debes mostrar junto a los datos. | | `meta.license` | URL | Licencia de reutilización (CC BY 4.0). | | `meta.web_url` | URL o `null` | Página equivalente en preciosgasolina.es, para citar y enlazar. | Convenciones de `data`: precios en euros con tres decimales (`€/L`, o `€/kg` con GNC, indicado en `unit`), porcentajes como número (`-1.28` = −1,28 %), fechas ISO 8601 y, en cada gasolinera o territorio, su `web_url`. ## Peticiones [Sección titulada «Peticiones»](#peticiones) * **Parámetros estrictos.** Un parámetro desconocido, repetido o con un valor fuera de rango devuelve `400` (`INVALID_PARAMETER`) con el motivo en `detail`. Los endpoints sin parámetros no admiten ninguno. * **Booleanos:** `true`, `false`, `1` o `0`. * **Coordenadas:** WGS84 dentro de España; se redondean a 3 decimales (≈ 100 m). * **URL:** 2.048 caracteres como máximo (`414` si es más larga). * **Cuerpo (solo `POST /v1/route/fuel`):** JSON con `Content-Type: application/json`, 32 KB como mucho. ## Paginación y tamaño [Sección titulada «Paginación y tamaño»](#paginación-y-tamaño) La API no pagina: cada endpoint de listas acepta `limit` (de 1 a 50; por defecto 10, salvo donde se indique) y filtros (`level`/`code`, `fuel`, `brand`, `open_24h`…). Para obtener **todas** las gasolineras o series completas, descarga los [datos abiertos](https://preciosgasolina.es/datos/) en CSV o JSON. ## Errores [Sección titulada «Errores»](#errores) Los errores siguen el RFC 9457: Ejemplo ilustrativo ```json { "type": "https://docs.preciosgasolina.es/conceptos/errores/#station-not-found", "title": "No encontrado", "status": 404, "detail": "No existe la gasolinera 99999999 (o ya no vende al público).", "code": "STATION_NOT_FOUND", "request_id": "e74dbaec2b574590", "instance": "/v1/stations/99999999" } ``` Comprueba `code` (estable) en tu código, no `title` ni `detail` (textos que pueden cambiar). Lista completa: [Errores](/conceptos/errores/). ## Cabeceras [Sección titulada «Cabeceras»](#cabeceras) | Cabecera | Cuándo | Significado | | ------------------ | ---------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `Cache-Control` | siempre | Datos con precios: `public, max-age=, stale-while-revalidate=300`. Contenido y catálogos: 6 horas. Territorios y ahorro: 1 día. `/v1/route/fuel`, `/v1/status` y errores: `no-store`. Respuestas con `meta.stale`: 60 s. | | `X-Request-Id` | siempre | Identificador de la petición (= `meta.request_id` o `request_id` del error). | | `X-Cache` | respuestas correctas | `hit`, `miss` o `stale` (caché de la API). | | `RateLimit-Policy` | respuestas correctas y `429` | Límite aplicado: `"rest";q=120;w=60` y, en las consultas pesadas, también `"heavy";q=30;w=60`. | | `Retry-After` | `429` y `503` | Segundos que debes esperar antes de reintentar. | Las respuestas llevan además `X-Robots-Tag: noindex`, `X-Content-Type-Options: nosniff` y `Strict-Transport-Security`. ## Límites [Sección titulada «Límites»](#límites) Por IP: **120 peticiones por minuto** (y 20 cada 10 segundos); **consultas pesadas, 30 por minuto**. Las pesadas son `GET /v1/stations/nearby`, `GET /v1/stations/{id}/history`, `GET /v1/routes/{slug}` y `POST /v1/route/fuel`. Todo sobre límites, topes y reintentos en [Límites de uso](/conceptos/limites/). ## Endpoints [Sección titulada «Endpoints»](#endpoints) Los 30 endpoints, agrupados como en el OpenAPI. Cada enlace lleva a su página de referencia con parámetros, respuestas y ejemplos. ### Precios | Método y ruta | Qué hace | Límite | MCP | | -------------------------------------------------------------------------- | --------------------------------------------- | ------ | ----------------- | | [`GET /v1/prices`](/referencia/api/operations/prices/) | Precio medio de hoy por carburante | normal | `get_fuel_prices` | | [`GET /v1/rankings/regions`](/referencia/api/operations/rankings_regions/) | Comunidades o provincias ordenadas por precio | normal | `compare_regions` | ### Gasolineras | Método y ruta | Qué hace | Límite | MCP | | ---------------------------------------------------------------------------- | -------------------------------------------------------------- | --------------- | -------------------- | | [`GET /v1/stations/nearby`](/referencia/api/operations/stations_nearby/) | Gasolineras cerca de unas coordenadas | pesada (30/min) | `find_fuel_near` | | [`GET /v1/stations/cheapest`](/referencia/api/operations/stations_cheapest/) | Las gasolineras más baratas | normal | `find_cheapest_fuel` | | [`GET /v1/stations/{id}`](/referencia/api/operations/station/) | Ficha de una gasolinera | normal | `get_station` | | [`GET /v1/search`](/referencia/api/operations/search/) | Buscar municipios, códigos postales, territorios y gasolineras | normal | `search_places` | ### Histórico | Método y ruta | Qué hace | Límite | MCP | | ------------------------------------------------------------------------------ | ---------------------------------- | --------------- | ------------------- | | [`GET /v1/stations/{id}/history`](/referencia/api/operations/station_history/) | Histórico diario de una gasolinera | pesada (30/min) | `get_price_history` | | [`GET /v1/history`](/referencia/api/operations/history/) | Histórico diario de un territorio | normal | `get_price_history` | | [`GET /v1/history/monthly`](/referencia/api/operations/history_monthly/) | Serie mensual de España desde 2005 | normal | `get_price_history` | ### Territorios | Método y ruta | Qué hace | Límite | MCP | | ---------------------------------------------------------------- | ------------------------------------ | ------ | --- | | [`GET /v1/territories`](/referencia/api/operations/territories/) | Comunidades, provincias y municipios | normal | — | ### Marcas | Método y ruta | Qué hace | Límite | MCP | | ------------------------------------------------------------ | ----------------------------------- | ------ | ---------------- | | [`GET /v1/brands`](/referencia/api/operations/brands/) | Marcas de gasolineras y sus precios | normal | `compare_brands` | | [`GET /v1/brands/{slug}`](/referencia/api/operations/brand/) | Ficha de una marca | normal | `compare_brands` | ### Productos | Método y ruta | Qué hace | Límite | MCP | | -------------------------------------------------------------- | ------------------------------------------- | ------ | -------------------- | | [`GET /v1/products/{id}`](/referencia/api/operations/product/) | AdBlue, gasóleo B, HVO, GNL y gasolinas E10 | normal | `get_product_prices` | ### Carreteras y rutas | Método y ruta | Qué hace | Límite | MCP | | ---------------------------------------------------------------------------- | ---------------------------- | --------------- | ----------------------- | | [`GET /v1/roads`](/referencia/api/operations/roads/) | Carreteras con gasolineras | normal | `find_fuel_on_road` | | [`GET /v1/roads/{slug}/stations`](/referencia/api/operations/road_stations/) | Gasolineras de una carretera | normal | `find_fuel_on_road` | | [`GET /v1/routes`](/referencia/api/operations/routes/) | Rutas por carretera | normal | `find_routes` | | [`GET /v1/routes/{slug}`](/referencia/api/operations/route/) | Una ruta y dónde repostar | pesada (30/min) | `get_route` | | [`POST /v1/route/fuel`](/referencia/api/operations/route_fuel/) | Dónde repostar en tu ruta | pesada (30/min) | `find_fuel_along_route` | ### Contenido | Método y ruta | Qué hace | Límite | MCP | | --------------------------------------------------------------------------- | --------------------------------------------- | ------ | -------------------- | | [`GET /v1/content`](/referencia/api/operations/content/) | Buscar guías, artículos y rutas | normal | `search_content` | | [`GET /v1/content/{type}/{slug}`](/referencia/api/operations/content_item/) | Una guía, un artículo o una ruta completos | normal | `get_article` | | [`GET /v1/reports`](/referencia/api/operations/reports/) | Informes mensuales disponibles | normal | `get_monthly_report` | | [`GET /v1/reports/{month}`](/referencia/api/operations/report/) | Informe de un mes | normal | `get_monthly_report` | | [`GET /v1/taxes`](/referencia/api/operations/taxes/) | Impuestos de los carburantes y rebaja vigente | normal | `explain_fuel_price` | ### Calculadoras | Método y ruta | Qué hace | Límite | MCP | | ---------------------------------------------------------------------------- | ----------------------------------------- | ------ | ----------------------- | | [`GET /v1/calc/trip-cost`](/referencia/api/operations/calc_trip/) | Coste en combustible de un viaje | normal | `calculate_trip_cost` | | [`GET /v1/calc/tank-cost`](/referencia/api/operations/calc_tank/) | Cuánto cuesta llenar el depósito | normal | `calculate_trip_cost` | | [`GET /v1/calc/savings`](/referencia/api/operations/calc_savings/) | Ahorro al repostar más barato | normal | `calculate_savings` | | [`GET /v1/calc/vehicle-costs`](/referencia/api/operations/calc_vehicle/) | Gasolina o diésel, eléctrico o combustión | normal | `compare_vehicle_costs` | | [`GET /v1/calc/adblue`](/referencia/api/operations/calc_adblue/) | Gasto en AdBlue | normal | `calculate_adblue` | | [`GET /v1/calc/price-breakdown`](/referencia/api/operations/calc_breakdown/) | Desglose del precio: impuestos y producto | normal | `explain_fuel_price` | ### Servicio | Método y ruta | Qué hace | Límite | MCP | | ------------------------------------------------------ | ------------------------------- | ------ | --- | | [`GET /v1/status`](/referencia/api/operations/status/) | Estado de la API y de los datos | normal | — | Estado del servicio `GET /v1/status` devuelve la versión de la API, la fecha de los datos y la próxima actualización, sin caché. Úsalo para comprobar que la API responde (sin abusar: cuenta en los límites). [Referencia generada desde el OpenAPI](/referencia/api/)Parámetros, esquemas de respuesta, errores y ejemplos en curl y JavaScript de cada endpoint. # Datos y cobertura > De dónde salen los datos de la API de Gasolina hoy, qué gasolineras y carburantes cubre, cuánto histórico hay y qué datos no incluye. Los precios de la API y del servidor MCP son los que **las gasolineras de venta al público de España comunican al Ministerio para la Transición Ecológica y el Reto Demográfico**, que los publica en el [Geoportal de Gasolineras](https://geoportalgasolineras.es/) y en su [servicio de datos abiertos](https://sedeaplicaciones.minetur.gob.es/ServiciosRESTCarburantes/PreciosCarburantes/EstacionesTerrestres/). Gasolina hoy los recoge dos veces al día, calcula medias, rankings e histórico y los sirve con una forma estable. ## Qué cubre [Sección titulada «Qué cubre»](#qué-cubre) | | | | ------------------------ | ------------------------------------------------------------------------------------------------------------------ | | Gasolineras | Unas 11.500 gasolineras de venta al público de toda España, Canarias, Ceuta y Melilla incluidas. | | Carburantes | Gasolina 95 E5, gasolina 98 E5, gasóleo A, gasóleo premium, GLP (autogás) y GNC. | | Otros productos | AdBlue, gasóleo B, HVO, GNL y gasolinas 95 y 98 E10, solo de las gasolineras que comunican su precio. | | Datos de cada gasolinera | Nombre, marca, dirección, código postal, municipio, provincia, comunidad, coordenadas, horario y si abre 24 horas. | | Territorios | Comunidades autónomas, provincias y municipios (con sus medias y rankings). | | Histórico diario | Hasta 90 días por territorio y por gasolinera. | | Serie mensual | España desde 2005 (gasolina 95 y gasóleo, con y sin impuestos), del Boletín Petrolero de la Unión Europea. | | Carreteras | Autovías, autopistas y nacionales con al menos 8 gasolineras localizadas. | | Contenido | Guías, artículos del blog y rutas por carretera de preciosgasolina.es. | ## Cómo se calculan los datos derivados [Sección titulada «Cómo se calculan los datos derivados»](#cómo-se-calculan-los-datos-derivados) * **Medias, mínimos y máximos** de cada territorio: con las gasolineras que tienen precio de ese carburante ese día (el número va en `stations`). * **Mediana:** además de la media, en `/v1/prices`. * **Variación diaria** (`change_vs_previous_day_pct`) y **frente a España** (`vs_spain_pct`): en porcentaje. * **Distritos y barrios:** el Ministerio solo da el municipio; la web los asigna por coordenadas, pero la API trabaja con comunidades, provincias y municipios. * **Carreteras:** cada gasolinera se asigna a una carretera por sus coordenadas, con un índice que se regenera de vez en cuando (las gasolineras nuevas pueden tardar en aparecer). * **Calculadoras:** las mismas fórmulas que las herramientas de la web. ## Qué no incluye [Sección titulada «Qué no incluye»](#qué-no-incluye) Precaución * **No hay datos en tiempo real ni por horas:** son dos actualizaciones al día. Ver [Frescura de los datos](/conceptos/frescura/). * **No hay puntos de recarga eléctrica**: solo gasolineras y sus carburantes. * **No hay precios de gasolineras que no los comunican** ni de las de uso privado (solo venta al público). * **No hay descuentos de tarjetas, apps o fidelización:** es el precio que la gasolinera comunica. * Los **productos** (AdBlue, HVO…) solo aparecen en las gasolineras que comunican su precio, no en todas las que los venden. ## Canarias, Ceuta y Melilla [Sección titulada «Canarias, Ceuta y Melilla»](#canarias-ceuta-y-melilla) No pagan el Impuesto sobre Hidrocarburos (tienen regímenes propios), así que sus precios son más bajos por fiscalidad. Están en la API como cualquier otro territorio, pero en los rankings de toda España van aparte salvo `include_low_tax=true`, y sus gasolineras y comunidades llevan `low_tax_area: true`. ## Exactitud [Sección titulada «Exactitud»](#exactitud) Los precios son los que comunica cada gasolinera: Gasolina hoy no los modifica, pero tampoco puede garantizar que coincidan con el surtidor en cada momento (una gasolinera puede cambiar el precio entre dos actualizaciones o comunicarlo con retraso). Muestra siempre la fecha de los datos. Las condiciones están en los [términos de uso](/terminos/). ## Descargas completas [Sección titulada «Descargas completas»](#descargas-completas) Si necesitas todas las gasolineras con sus precios de hoy o las medias diarias de 90 días de todos los territorios, usa los [datos abiertos](https://preciosgasolina.es/datos/) de la web (CSV y JSON, misma licencia) en lugar de recorrer la API. # Errores > 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 [Sección titulada «Formato»](#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 [Sección titulada «Códigos»](#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) [Sección titulada «INVALID_PARAMETER (400)»](#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) [Sección titulada «INVALID_JSON (400)»](#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) [Sección titulada «Recursos no encontrados (404)»](#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) [Sección titulada «ENDPOINT_NOT_FOUND (404)»](#endpoint_not_found-404) La ruta no existe. Revisa la [referencia](/referencia/): todas las rutas empiezan por `/v1/` y terminan sin extensión. ### METHOD_NOT_ALLOWED (405) [Sección titulada «METHOD_NOT_ALLOWED (405)»](#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) [Sección titulada «PAYLOAD_TOO_LARGE (413)»](#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) [Sección titulada «URI_TOO_LONG (414)»](#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) [Sección titulada «UNSUPPORTED_MEDIA_TYPE (415)»](#unsupported_media_type-415) Un `POST` sin `Content-Type: application/json`. Añade la cabecera. ### RATE_LIMITED (429) [Sección titulada «RATE_LIMITED (429)»](#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](/conceptos/limites/). ### INTERNAL_ERROR (500) [Sección titulada «INTERNAL_ERROR (500)»](#internal_error-500) Error inesperado de la API. Puedes reintentar una vez pasados unos segundos; si se repite, escríbenos a con el `request_id`. ### ENDPOINT_DISABLED (503) [Sección titulada «ENDPOINT_DISABLED (503)»](#endpoint_disabled-503) El endpoint (o toda la API) está desactivado temporalmente, por ejemplo por mantenimiento. Lleva `Retry-After: 3600`. ### TEMPORARILY_UNAVAILABLE (503) [Sección titulada «TEMPORARILY_UNAVAILABLE (503)»](#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](/conceptos/frescura/). ## Errores del servidor MCP [Sección titulada «Errores del servidor MCP»](#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 …`). # Frescura de los datos > Los precios de la API de Gasolina hoy se actualizan dos veces al día, hacia las 8:00 y las 20:00. Cómo leer last_updated, next_update y stale. Los precios se actualizan **dos veces al día, hacia las 8:00 y las 20:00 (hora peninsular)**, cuando Gasolina hoy recoge los datos que las gasolineras han comunicado al Ministerio. **No son en tiempo real**: entre dos actualizaciones, la API devuelve siempre los mismos precios, y una gasolinera puede haber cambiado el suyo en el surtidor. ## Los campos de frescura [Sección titulada «Los campos de frescura»](#los-campos-de-frescura) Cada respuesta (y cada resultado del MCP) lleva en `meta`: | Campo | Ejemplo | Para qué sirve | | ------------------ | -------------------------- | ------------------------------------------------------------------------------------------------------- | | `last_updated` | `2026-10-07T06:12:00.000Z` | Cuándo se actualizaron los datos. Muéstralo siempre, en hora de Madrid (en el ejemplo, las 8:12). | | `next_update` | `2026-10-07T18:10:00.000Z` | Cuándo está prevista la próxima actualización (en el ejemplo, las 20:10 de Madrid). Úsalo para cachear. | | `data_age_seconds` | `7430` | Antigüedad de los datos en segundos en el momento de responder. | | `stale` | `false` | `true` si se sirve la última copia buena porque la fuente no respondió. | Las fechas van en UTC (sufijo `Z`). En horario de verano, Madrid va dos horas por delante (UTC+2) y en invierno, una (UTC+1). Nota `next_update` es la hora **prevista**. La actualización tarda unos minutos y puede retrasarse; si al volver a pedir los datos `last_updated` no ha cambiado, espera unos minutos. ## Histórico [Sección titulada «Histórico»](#histórico) * El **histórico diario** (`/v1/history`, `/v1/stations/{id}/history`) tiene un punto por día. El valor definitivo del día anterior se completa una vez al día, por la mañana. * La **serie mensual** (`/v1/history/monthly`) viene del Boletín Petrolero de la UE y se actualiza periódicamente, no dos veces al día. * Los **informes** (`/v1/reports`) solo existen para meses cerrados. ## Caché alineada con las actualizaciones [Sección titulada «Caché alineada con las actualizaciones»](#caché-alineada-con-las-actualizaciones) La API guarda cada respuesta con precios **hasta la próxima actualización**: la cabecera `Cache-Control` de esas respuestas es `public, max-age=, stale-while-revalidate=300`. Haz lo mismo en tu aplicación: guarda la respuesta hasta `meta.next_update` y no vuelvas a pedirla antes. Ver [Integrar en tu web](/guias/integrar-en-tu-web/). ## `stale`: cuando la fuente no responde [Sección titulada «stale: cuando la fuente no responde»](#stale-cuando-la-fuente-no-responde) Si la base de datos de la que lee la API falla o va lenta, o si la API está protegiéndose (ver [Límites](/conceptos/limites/#presupuesto-mensual-y-protecci%C3%B3n-del-servicio)), no se deja de responder: se sirve **la última copia buena** de esa misma respuesta (se guarda hasta 7 días) con `meta.stale: true`, `X-Cache: stale` y `Cache-Control: public, max-age=60`. Los datos son correctos, pero pueden ser de una actualización anterior: muestra `last_updated` y vuelve a pedirlos en un minuto. Si no hay copia, la API responde `503` (`TEMPORARILY_UNAVAILABLE`) con `Retry-After`. ## Cómo decirlo en tu interfaz [Sección titulada «Cómo decirlo en tu interfaz»](#cómo-decirlo-en-tu-interfaz) * «Precios del Ministerio actualizados hoy a las 8:12.» * «Datos de las 20:10. Próxima actualización hacia las 8:00.» * En asistentes: «según los datos del Ministerio de esta mañana…», nunca «ahora mismo». # Límites de uso > Límites por IP de la API REST (120/min, 20 cada 10 s, 30/min pesadas) y del MCP (60 mensajes y 30 herramientas/min), topes, 429 y Retry-After. La API y el servidor MCP son gratuitos y no piden clave, así que se protegen con **límites por IP**, **topes en los parámetros** y un **presupuesto mensual**. Con un uso normal (y con caché hasta `meta.next_update`) no deberías llegar a ellos. La web preciosgasolina.es tiene siempre prioridad: si hay presión, la API se degrada sola. ## Límites por IP [Sección titulada «Límites por IP»](#límites-por-ip) | Qué | Límite | | ---------------------------------------------------- | -------------------------------------------------------- | | API REST | **120 peticiones por minuto** y 20 cada 10 segundos | | Consultas pesadas de la API REST | **30 por minuto** (cuentan también en el límite general) | | Servidor MCP: mensajes | **60 por minuto** | | Servidor MCP: llamadas a herramientas (`tools/call`) | **30 por minuto** (de esos 60 mensajes) | Son **consultas pesadas** las que hacen cálculos geográficos o leen mucho histórico: * `GET /v1/stations/nearby` (gasolineras cerca de unas coordenadas) * `GET /v1/stations/{id}/history` (histórico de una gasolinera) * `GET /v1/routes/{slug}` (ruta del catálogo con sus gasolineras) * `POST /v1/route/fuel` (dónde repostar en tu ruta) Las peticiones a rutas que no existen también cuentan. Las direcciones IPv6 se agrupan por su prefijo `/64`. La IP solo se usa para contar: no se guarda. Los contadores son aproximados y por centro de datos, así que el corte puede no ser exacto al segundo. ## Qué pasa al superarlos [Sección titulada «Qué pasa al superarlos»](#qué-pasa-al-superarlos) La API responde **`429 Too Many Requests`** con el código `RATE_LIMITED`, la cabecera **`Retry-After: 60`** y `RateLimit-Policy` con el límite aplicado: Ejemplo ilustrativo ```http HTTP/2 429 content-type: application/problem+json; charset=utf-8 retry-after: 60 ratelimit-policy: "rest";q=120;w=60, "heavy";q=30;w=60 ``` Ejemplo ilustrativo ```json { "type": "https://docs.preciosgasolina.es/conceptos/errores/#rate-limited", "title": "Demasiadas peticiones", "status": 429, "detail": "Has superado el límite de 30 consultas pesadas por minuto. Espera un minuto.", "code": "RATE_LIMITED", "request_id": "…", "instance": "/v1/stations/nearby" } ``` **Espera los segundos de `Retry-After` antes de reintentar**; reintentar antes solo alarga el bloqueo. En el servidor MCP, el `429` lleva un error JSON-RPC («Demasiados mensajes» o «Demasiadas llamadas a herramientas») y también `Retry-After: 60`. Código de ejemplo con reintentos en [Integrar en tu web](/guias/integrar-en-tu-web/#un-cliente-completo). ## Topes de parámetros y tamaños [Sección titulada «Topes de parámetros y tamaños»](#topes-de-parámetros-y-tamaños) | Parámetro o tamaño | Tope | | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------ | | `limit` (resultados por petición) | 1–50; por defecto 10 (en `/v1/search`, 1–20 y por defecto 8; en `/v1/routes`, por defecto 20; en `/v1/brands`, por defecto 50) | | `radius_km` (radio) | hasta 50 km; por defecto 5 | | `days` (histórico diario) | 1–90; por defecto 30 | | `points` (ruta propia) | de 2 a 200 puntos y 1500 km como mucho | | `corridor_km` (distancia a la ruta) | hasta 10 km; por defecto 3 | | `q` / `query` (texto de búsqueda) | 2–100 caracteres | | URL | 2048 caracteres (`414` si es más larga) | | Cuerpo de `POST /v1/route/fuel` | 32 KB (`413` si es mayor) | | Mensaje MCP | 64 KB | | Resultado de una herramienta MCP | unos 20 KB: las listas se recortan a 10 elementos (`truncated: true`) | Un valor fuera de estos rangos devuelve `400` (`INVALID_PARAMETER`) con el motivo. ## Presupuesto mensual y protección del servicio [Sección titulada «Presupuesto mensual y protección del servicio»](#presupuesto-mensual-y-protección-del-servicio) Además de los límites por IP, la API tiene un **presupuesto global de 1.500.000 peticiones al mes** (para todos los usuarios a la vez) y un disyuntor que deja de consultar la base de datos si esta falla varias veces seguidas. En los dos casos la API no se cae, se degrada: 1. Sirve lo que ya tiene calculado en caché (respuesta normal). 2. Si no lo tiene, sirve la **última copia buena** de esa respuesta con `meta.stale: true`. 3. Si tampoco hay copia, responde **`503`** con `TEMPORARILY_UNAVAILABLE` y `Retry-After`. Un endpoint o una herramienta pueden desactivarse temporalmente (por ejemplo, por mantenimiento): el endpoint responde `503` con `ENDPOINT_DISABLED` y `Retry-After: 3600`, y la herramienta devuelve `isError: true` con «Herramienta desactivada temporalmente». ## Si necesitas más [Sección titulada «Si necesitas más»](#si-necesitas-más) Consejo * **Cachea** hasta `meta.next_update`: los datos solo cambian dos veces al día. * Para **todas las gasolineras** o **todos los territorios**, descarga los [datos abiertos](https://preciosgasolina.es/datos/) (CSV y JSON, misma licencia) en lugar de recorrer la API. * Si tu caso de uso necesita límites más altos, escríbenos a contando qué haces. Los límites pueden cambiar con el uso real; los cambios se anotan en el [registro de cambios](/changelog/). # Seguridad y privacidad > La API y el MCP de Gasolina hoy son de solo lectura, sin cookies ni cuentas; la IP no se guarda y las coordenadas se redondean a 3 decimales. La API REST y el servidor MCP están diseñados para no necesitar datos personales: no hay cuentas, claves, cookies ni sesiones, y no se puede escribir nada. ## Solo lectura [Sección titulada «Solo lectura»](#solo-lectura) * Todas las operaciones son de lectura: `GET`, `HEAD` y `OPTIONS`, y un único `POST` (`/v1/route/fuel`) que solo calcula con los puntos que envías y no los guarda. * Las 21 herramientas MCP se declaran de solo lectura (`readOnlyHint: true`, `destructiveHint: false`) e idempotentes. * La API lee los datos con una clave pública de solo lectura; no tiene acceso de escritura a la base de datos. ## Qué datos tuyos se usan [Sección titulada «Qué datos tuyos se usan»](#qué-datos-tuyos-se-usan) | Dato | Uso | | ---------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | Dirección IP | Solo para contar las peticiones de los [límites](/conceptos/limites/) (las IPv6, agrupadas por su prefijo `/64`). La API no la guarda. | | Coordenadas (`lat`, `lng`, puntos de una ruta) | Se **redondean a 3 decimales** (unos 100 m) antes de usarlas: no identifican una dirección exacta y peticiones cercanas comparten caché. Las respuestas en caché no llevan datos de quien las pidió. | | Parámetros y endpoint | Se miden de forma agregada (endpoint o herramienta, estado, caché y duración) para mantener el servicio, sin datos personales. | No hay cookies, ni identificadores de usuario, ni seguimiento publicitario. Más información en la [política de privacidad](https://preciosgasolina.es/privacidad/) de preciosgasolina.es. ## CORS y cabeceras [Sección titulada «CORS y cabeceras»](#cors-y-cabeceras) * **CORS abierto:** `Access-Control-Allow-Origin: *` sin credenciales, para que cualquier web pueda llamar a la API desde el navegador. Como no hay cookies ni autenticación, no hay nada que proteger con CORS. * **Servidor MCP:** si la petición trae `Origin`, debe ser `https://` (o `localhost`); otros orígenes reciben `403`. * Todas las respuestas llevan `Strict-Transport-Security`, `X-Content-Type-Options: nosniff`, `Content-Security-Policy: default-src 'none'; frame-ancestors 'none'`, `Referrer-Policy: no-referrer` y `X-Robots-Tag: noindex, nofollow` (`api.` y `mcp.` no son páginas y no se indexan; esta documentación sí). * Solo HTTPS. ## Textos de terceros [Sección titulada «Textos de terceros»](#textos-de-terceros) Los nombres, direcciones y horarios de las gasolineras vienen del Ministerio tal como los comunican las gasolineras. La API les quita los caracteres de control y los recorta (200 caracteres como mucho), pero siguen siendo **datos de terceros**: Precaución * **Escápalos** al pintarlos en HTML (no los insertes con `innerHTML`). * Si construyes un agente, trátalos como datos, nunca como instrucciones para el modelo. ## Robustez [Sección titulada «Robustez»](#robustez) La API valida cada parámetro con un esquema estricto, limita el tamaño de la URL (2.048 caracteres) y del cuerpo (32 KB; 64 KB en el MCP) y aplica límites por IP y un presupuesto global. Si detectas un problema de seguridad, escríbenos a . # Versionado > Versionado de la API de Gasolina hoy: v1 en la ruta, cambios compatibles sin aviso, cambios incompatibles en una nueva versión, Deprecation y Sunset. La API está en la versión **`v1`**, que va en la ruta (`https://api.preciosgasolina.es/v1/…`) y en cada respuesta (`meta.api_version`). El OpenAPI (`info.version`) y el servidor MCP (`serverInfo.version`) tienen además su propia versión semántica. ## Cambios compatibles (sin aviso previo) [Sección titulada «Cambios compatibles (sin aviso previo)»](#cambios-compatibles-sin-aviso-previo) Dentro de `v1` se pueden hacer, sin cambiar de versión, cambios que no rompen un cliente bien escrito: * Añadir endpoints, herramientas MCP, recursos o prompts. * Añadir **campos nuevos** en `data` o en `meta`. * Añadir **parámetros opcionales** nuevos. * Añadir valores nuevos a listas abiertas (por ejemplo, nuevos tipos de resultado en `/v1/search` o nuevos códigos `*_NOT_FOUND`). * Cambiar los textos de `title`, `detail`, `note` y otros textos legibles. * Ajustar los límites y topes (se anotan en el [registro de cambios](/changelog/)). Para que tu cliente no se rompa: * **Ignora los campos que no conozcas** (no valides la respuesta con un esquema estricto que rechace campos extra). * Comprueba `code` en los errores, no `detail`. * No dependas del orden de los campos de un objeto. Ojo: la API sí es estricta con lo que *recibe*. Un parámetro desconocido devuelve `400`, así que no envíes parámetros que el endpoint no documente. ## Cambios incompatibles [Sección titulada «Cambios incompatibles»](#cambios-incompatibles) Quitar o renombrar un endpoint, un campo o un parámetro, o cambiar su tipo o su significado, solo se hará en una **nueva versión** (`/v2/`), que convivirá con `v1` durante un periodo de transición. ## Obsolescencia: `Deprecation` y `Sunset` [Sección titulada «Obsolescencia: Deprecation y Sunset»](#obsolescencia-deprecation-y-sunset) Cuando un endpoint vaya a retirarse, sus respuestas llevarán las cabeceras estándar: * `Deprecation` ([RFC 9745](https://www.rfc-editor.org/rfc/rfc9745)): desde cuándo está obsoleto. * `Sunset` ([RFC 8594](https://www.rfc-editor.org/rfc/rfc8594)): fecha a partir de la cual dejará de funcionar. * `Link` con `rel="deprecation"`: página con la explicación y la alternativa. El OpenAPI marcará esas operaciones con `deprecated: true` y el cambio se anunciará en el [registro de cambios](/changelog/). Hoy ningún endpoint está obsoleto. # Calculadoras > Coste de un viaje y del depósito, ahorro, gasolina o diésel, AdBlue y desglose de impuestos con las calculadoras de la API de Gasolina hoy. Los endpoints de **`/v1/calc/…`** usan las mismas fórmulas que las [calculadoras de preciosgasolina.es](https://preciosgasolina.es/herramientas/) y, si no indicas un precio, el precio medio de hoy (de España o de la provincia que pidas con `province`). Así tu app y la web dan el mismo resultado. | Endpoint | Calcula | Parámetros obligatorios | | ------------------------------ | --------------------------------------------------------- | ----------------------------------------------------- | | `GET /v1/calc/trip-cost` | Coste en combustible de un viaje | `km` **o** `from_lat`, `from_lng`, `to_lat`, `to_lng` | | `GET /v1/calc/tank-cost` | Cuánto cuesta llenar el depósito | `capacity` | | `GET /v1/calc/savings` | Ahorro al repostar más barato y si compensa el desvío | `usual_price`, `cheap_price` | | `GET /v1/calc/vehicle-costs` | Gasolina frente a diésel, o eléctrico frente a combustión | `compare`, `km_per_year` | | `GET /v1/calc/adblue` | Gasto en AdBlue al mes y al año | `km_per_year` | | `GET /v1/calc/price-breakdown` | Cuánto de cada litro son impuestos | ninguno | Los precios van en €/L (€/kg con GNC), los consumos en L/100 km y las distancias en km. Todas las respuestas incluyen en `inputs` los valores usados (también los que la API ha puesto por defecto) y `price_basis`, que dice de dónde sale el precio («media de España hoy», «precio indicado»…). ## Coste de un viaje [Sección titulada «Coste de un viaje»](#coste-de-un-viaje) Parámetros: `fuel` (por defecto `gasoline_95`), `km` (de ida, hasta 20.000) o las coordenadas de origen y destino (la distancia se estima en línea recta × 1,25), `round_trip`, `consumption` (hasta 40), `price` (hasta 5 €), `province` (código o slug, para usar su media) y `people` (1–9, para repartir el coste). * curl ```sh curl "https://api.preciosgasolina.es/v1/calc/trip-cost?fuel=diesel&km=350&consumption=6.5&round_trip=true&people=2" ``` * JavaScript ```js const params = new URLSearchParams({ fuel: "diesel", km: "350", consumption: "6.5", round_trip: "true", people: "2" }); const { data } = await (await fetch("https://api.preciosgasolina.es/v1/calc/trip-cost?" + params)).json(); console.log(`${data.distance.total_km} km: ${data.cost_eur} € (${data.cost_per_person_eur} € por persona)`); ``` * Python ```python import requests d = requests.get( "https://api.preciosgasolina.es/v1/calc/trip-cost", params={"fuel": "diesel", "km": 350, "consumption": 6.5, "round_trip": "true", "people": 2}, timeout=10, ).json()["data"] print(d["distance"]["total_km"], "km:", d["cost_eur"], "€,", d["cost_per_person_eur"], "€ por persona") ``` Ejemplo ilustrativo: los valores no son precios reales ```json { "data": { "fuel": "diesel", "unit": "L", "currency": "EUR", "inputs": { "consumption_per_100km": 6.5, "price": 1.481, "price_basis": "media de España hoy", "round_trip": true, "people": 2 }, "distance": { "one_way_km": 350, "total_km": 700, "straight_line_km": null, "note": null }, "fuel_quantity": 45.5, "cost_eur": 67.39, "cost_per_person_eur": 33.69, "cost_per_100km_eur": 9.63 }, "meta": { "web_url": "https://preciosgasolina.es/herramientas/calculadora-ruta/", "…": "…" } } ``` ## Llenar el depósito [Sección titulada «Llenar el depósito»](#llenar-el-depósito) `capacity` (litros, hasta 200), `level` del depósito al empezar (`vacio`, `reserva` —por defecto—, `1-4`, `1-2` o `3-4`), `fuel`, `price` y `province`. Devuelve el coste con el precio medio y con el más barato de hoy, y la diferencia (`possible_saving_eur`). ```sh curl "https://api.preciosgasolina.es/v1/calc/tank-cost?capacity=50&level=reserva&fuel=gasoline_95" ``` ## Ahorro al repostar más barato [Sección titulada «Ahorro al repostar más barato»](#ahorro-al-repostar-más-barato) `usual_price` y `cheap_price` (€/L), y opcionalmente `quantity_per_refuel`, `refuels_per_month`, `detour_km` (ida y vuelta) y `consumption`. Devuelve el ahorro por repostaje, al mes y al año, el coste del desvío, el ahorro neto, los kilómetros de desvío a partir de los que deja de compensar (`break_even_detour_km`) y un veredicto (`verdict`: `worth`, `not-worth`, `even` o `no-saving`). ```sh curl "https://api.preciosgasolina.es/v1/calc/savings?usual_price=1.55&cheap_price=1.47&detour_km=6" ``` ## Gasolina o diésel, eléctrico o combustión [Sección titulada «Gasolina o diésel, eléctrico o combustión»](#gasolina-o-diésel-eléctrico-o-combustión) `compare=petrol_vs_diesel` compara un coche de gasolina con uno diésel; `compare=ev_vs_fuel`, un eléctrico con uno de combustión. Siempre con `km_per_year`. Opcionales: consumos (`petrol_consumption`, `diesel_consumption`, `ev_consumption` en kWh/100 km), precios (`petrol_price`, `diesel_price`, `electricity_price` en €/kWh) y sobrecostes (`diesel_extra_price`, `diesel_extra_yearly_cost`, `ev_extra_price`). Devuelve el coste por 100 km, el ahorro al año, los años para amortizar y los kilómetros al año a partir de los que compensa. ```sh curl "https://api.preciosgasolina.es/v1/calc/vehicle-costs?compare=petrol_vs_diesel&km_per_year=20000&diesel_extra_price=1500" ``` ## AdBlue [Sección titulada «AdBlue»](#adblue) `km_per_year` (obligatorio), `litres_per_1000km`, `price` (por defecto, la media de hoy en surtidor) y `tank_litres`. Devuelve litros y euros al mes, al año y cada 1.000 km. ```sh curl "https://api.preciosgasolina.es/v1/calc/adblue?km_per_year=20000" ``` ## Desglose del precio: impuestos [Sección titulada «Desglose del precio: impuestos»](#desglose-del-precio-impuestos) `fuel` (`gasoline_95`, `gasoline_98`, `diesel` o `diesel_premium`), `price` (por defecto, la media de hoy), `province` (cambia el régimen fiscal en Canarias, Ceuta y Melilla) y `tank_litres`. Devuelve por litro el IVA, el Impuesto sobre Hidrocarburos (con la rebaja vigente, si la hay), el total de impuestos y lo que queda para producto, logística y margen, con las fuentes legales. ```sh curl "https://api.preciosgasolina.es/v1/calc/price-breakdown?fuel=diesel" ``` Los tipos de impuestos y los tramos de la rebaja están también en `GET /v1/taxes`. Nota Las calculadoras son estimaciones con las fórmulas y supuestos de las herramientas de la web. Si no indicas consumo o precio, la API usa valores típicos y te los devuelve en `inputs`. ## Con el servidor MCP [Sección titulada «Con el servidor MCP»](#con-el-servidor-mcp) `calculate_trip_cost` (viaje y, con `tank_capacity`, también el depósito), `calculate_savings`, `compare_vehicle_costs`, `calculate_adblue` y `explain_fuel_price` (desglose más impuestos y rebaja). Ejemplo: «¿Cuánto me cuesta ir de Madrid a Valencia con 6,5 L/100 km?». # Contenido y guías > Busca y lee las guías, artículos del blog y rutas de preciosgasolina.es en Markdown, con preguntas frecuentes y fuentes, e impuestos con /v1/taxes. La API da acceso al contenido editorial de preciosgasolina.es (guías, artículos del blog y rutas) para que tu app o tu agente pueda responder dudas («¿qué es la gasolina E10?») con un texto revisado y enlazar la fuente. Busca con **`GET /v1/content`** y lee una pieza completa con **`GET /v1/content/{type}/{slug}`**. ## Buscar [Sección titulada «Buscar»](#buscar) | Parámetro | Valores | | --------- | --------------------------------------------------------------------- | | `q` | Texto a buscar (2–100 caracteres). Sin `q`, las piezas más recientes. | | `type` | `guide` (guías), `post` (blog) o `route` (rutas). | | `tag` | Una etiqueta exacta (p. ej. `e10`). | | `limit` | 1–50 (por defecto 10). | * curl ```sh curl "https://api.preciosgasolina.es/v1/content?q=e10&limit=3" ``` * JavaScript ```js const { data } = await (await fetch("https://api.preciosgasolina.es/v1/content?" + new URLSearchParams({ q: "e10", limit: "3" }))).json(); for (const item of data.results) console.log(`[${item.type}] ${item.title}\n${item.answer}\n${item.web_url}\n`); ``` * Python ```python import requests data = requests.get("https://api.preciosgasolina.es/v1/content", params={"q": "e10", "limit": 3}, timeout=10).json()["data"] for item in data["results"]: print(f'[{item["type"]}] {item["title"]}\n{item["answer"]}\n{item["web_url"]}\n') ``` Cada resultado trae `type`, `slug`, `title`, `description`, `answer` (la respuesta directa de la pieza), `published`, `updated`, `tags` y `web_url`. `data.total` es el número de coincidencias. Ejemplo ilustrativo ```json { "data": { "query": "e10", "type": null, "total": 2, "results": [ { "type": "guide", "slug": "tipos-de-carburante", "title": "Tipos de carburante: gasolina, diésel y gas", "description": "Tipos de carburante en las gasolineras de España: gasolina, gasóleo, GLP, GNC, gasóleo B y C y biocombustibles E5, E10 y B7. Qué es cada uno.", "answer": "Un combustible es una sustancia que libera energía al quemarse y mueve el motor…", "published": "2026-06-15", "updated": "2026-10-06", "tags": [], "web_url": "https://preciosgasolina.es/guias/tipos-de-carburante/" } ] }, "meta": { "…": "…" } } ``` ## Leer una pieza completa [Sección titulada «Leer una pieza completa»](#leer-una-pieza-completa) ```sh curl "https://api.preciosgasolina.es/v1/content/guide/tipos-de-carburante" ``` Devuelve los campos de la búsqueda más `heading` (el titular de la página), `body_markdown` (el texto completo en Markdown), `faqs` (preguntas frecuentes, `q` y `a`), `sources` (fuentes con `name` y `url`) y `related` (slugs relacionados). Las rutas traen además su recorrido, fotos y datos prácticos (ver [Dónde repostar en una ruta](/guias/repostar-en-una-ruta/)). Si el slug no existe, la API responde `404` con `GUIDE_NOT_FOUND`, `ARTICLE_NOT_FOUND` (blog) o `ROUTE_NOT_FOUND`. Cita siempre la fuente Si muestras o resumes una guía, enlaza su `web_url` y menciona a Gasolina hoy. Ver [Atribución y licencia](/empezar/atribucion-y-licencia/). ## Impuestos de los carburantes [Sección titulada «Impuestos de los carburantes»](#impuestos-de-los-carburantes) `GET /v1/taxes` (sin parámetros) devuelve el IVA de los carburantes, el Impuesto sobre Hidrocarburos por epígrafe, los tramos de la rebaja vigente (Real Decreto-ley 25/2026) y si hay uno en vigor hoy, el régimen de Canarias, los mínimos de la Unión Europea y las fuentes legales. Para aplicarlo a un precio concreto, usa [`/v1/calc/price-breakdown`](/guias/calculadoras/#desglose-del-precio-impuestos). ## Caché [Sección titulada «Caché»](#caché) El contenido cambia cuando se publica en la web, no con los precios: `/v1/content`, `/v1/content/{type}/{slug}` y `/v1/taxes` se cachean 6 horas (`Cache-Control: public, max-age=21600`). ## Con el servidor MCP [Sección titulada «Con el servidor MCP»](#con-el-servidor-mcp) `search_content` («¿Qué es la gasolina E10?») y `get_article` (una pieza completa). También están como recursos: `preciosgasolina://guias/{slug}`, `preciosgasolina://blog/{slug}` y `preciosgasolina://rutas/{slug}` (ver [Recursos y prompts](/mcp/recursos-y-prompts/)). # Gasolinera más barata cerca > Encuentra con la API de Gasolina hoy las gasolineras más baratas o más cercanas a unas coordenadas, con filtros de 24 horas y marca. Con código. Para encontrar dónde repostar más barato cerca de un punto, usa **`GET /v1/stations/cheapest`** con `lat`, `lng` y `radius_km`: devuelve las gasolineras del radio ordenadas por precio. Si prefieres ordenarlas por distancia, usa **`GET /v1/stations/nearby`** con `sort=distance`. ## Qué endpoint usar [Sección titulada «Qué endpoint usar»](#qué-endpoint-usar) | Necesitas | Endpoint | Orden | Límite | | ------------------------------------------------ | --------------------------------------------------- | -------------------- | ---------------------------- | | Las más baratas a menos de X km | `GET /v1/stations/cheapest?lat=…&lng=…&radius_km=…` | precio | normal (120/min) | | Las más cercanas (o por precio) con su distancia | `GET /v1/stations/nearby?lat=…&lng=…&sort=distance` | `price` o `distance` | **consulta pesada** (30/min) | Los dos aceptan `fuel` (por defecto `gasoline_95`), `limit` (1–50, por defecto 10), `open_24h=true` y `brand=`. El radio va de más de 0 a 50 km y, si no lo indicas, es de 5 km. Las gasolineras de `nearby` (y las de `cheapest` por coordenadas) traen `distance_km`. ## Paso a paso [Sección titulada «Paso a paso»](#paso-a-paso) 1. **Consigue las coordenadas.** Del navegador (`navigator.geolocation`), de tu propia base de datos o de la API: `GET /v1/territories?level=municipality&parent=` devuelve `lat` y `lng` de cada municipio. 2. **Pide las más baratas del radio.** * curl ```sh curl "https://api.preciosgasolina.es/v1/stations/cheapest?fuel=diesel&lat=40.4168&lng=-3.7038&radius_km=10&limit=5" ``` * JavaScript ```js async function masBaratasCerca({ lat, lng, fuel = "gasoline_95", radiusKm = 5, limit = 5, open24h = false }) { const url = new URL("https://api.preciosgasolina.es/v1/stations/cheapest"); url.search = new URLSearchParams({ fuel, lat, lng, radius_km: radiusKm, limit, ...(open24h && { open_24h: "true" }) }); const res = await fetch(url); if (!res.ok) { const err = await res.json(); // application/problem+json throw new Error(`${err.code}: ${err.detail}`); } return res.json(); // { data, meta } } const { data, meta } = await masBaratasCerca({ lat: 40.4168, lng: -3.7038, fuel: "diesel", radiusKm: 10 }); for (const s of data.stations) console.log(s.price, s.name, s.distance_km + " km", s.web_url); ``` * Python ```python import requests def mas_baratas_cerca(lat, lng, fuel="gasoline_95", radius_km=5, limit=5, open_24h=False): params = {"fuel": fuel, "lat": lat, "lng": lng, "radius_km": radius_km, "limit": limit} if open_24h: params["open_24h"] = "true" r = requests.get("https://api.preciosgasolina.es/v1/stations/cheapest", params=params, timeout=10) if not r.ok: err = r.json() # application/problem+json raise RuntimeError(f'{err["code"]}: {err["detail"]}') return r.json() body = mas_baratas_cerca(40.4168, -3.7038, fuel="diesel", radius_km=10) for s in body["data"]["stations"]: print(s["price"], s["name"], s.get("distance_km"), "km", s["web_url"]) ``` 3. **Muestra el resultado con su fecha y la fuente.** Cada gasolinera trae `price`, `price_updated_at`, `is_24h`, `hours`, su dirección y su `web_url`. Muestra `meta.attribution` y la fecha de `meta.last_updated` (ver [Atribución](/empezar/atribucion-y-licencia/)). Ejemplo ilustrativo: los valores no son precios reales ```json { "data": { "fuel": "diesel", "unit": "L", "currency": "EUR", "center": { "lat": 40.417, "lng": -3.704 }, "radius_km": 10, "note": null, "stations": [ { "id": 12345, "name": "Estación de ejemplo", "brand": { "slug": "marca-ejemplo", "name": "Marca Ejemplo" }, "address": "Calle de Ejemplo, 1", "postal_code": "28001", "municipality": { "id": 4354, "name": "Madrid" }, "province": { "code": "28", "name": "Madrid" }, "community": { "code": "13", "name": "Comunidad de Madrid" }, "lat": 40.39, "lng": -3.65, "is_24h": true, "hours": "L-D: 24H", "low_tax_area": false, "web_url": "https://preciosgasolina.es/gasolineras/estacion-de-ejemplo-12345/", "price": 1.459, "price_updated_at": "2026-10-07T06:12:00.000+00:00", "distance_km": 5.47 } ] }, "meta": { "last_updated": "2026-10-07T06:12:00.000Z", "attribution": "Fuente: Gasolina hoy (preciosgasolina.es), con datos del…", "web_url": "https://preciosgasolina.es/mapa-gasolineras/", "…": "…" } } ``` Fíjate en que `center` sale redondeado a 3 decimales: la API redondea siempre las coordenadas (unos 100 m) para no identificar a nadie y compartir caché. ## Ordenar por distancia [Sección titulada «Ordenar por distancia»](#ordenar-por-distancia) ```sh curl "https://api.preciosgasolina.es/v1/stations/nearby?lat=40.4168&lng=-3.7038&radius_km=3&fuel=gasoline_95&sort=distance&limit=10" ``` `nearby` cuenta como **consulta pesada** (30 por minuto por IP): úsalo cuando el usuario lo pida, no en cada movimiento del mapa. ## Filtros útiles [Sección titulada «Filtros útiles»](#filtros-útiles) * **Abiertas 24 horas:** `open_24h=true`. * **Una marca:** `brand=repsol` (slug de la marca; lista en `GET /v1/brands`). * **Más resultados:** `limit=50` como máximo. Para listados completos de una zona, descarga los [datos abiertos](https://preciosgasolina.es/datos/). En una ciudad o provincia Si en lugar de un punto tienes un municipio o una provincia, usa `level` + `code`: [Las más baratas de una provincia](/guias/mas-baratas-de-una-provincia/). ## Con el servidor MCP [Sección titulada «Con el servidor MCP»](#con-el-servidor-mcp) Las herramientas equivalentes son `find_cheapest_fuel` (con `lat`, `lng` y `radius_km`) y `find_fuel_near` (con `sort`). Ejemplo de pregunta: «Gasolineras cerca de la estación de Atocha». Ver [Herramientas del MCP](/mcp/herramientas/). # Gasolineras por carretera > Lista las gasolineras de una autovía, autopista o nacional (A-6, AP-7, N-340…) con su punto kilométrico y sentido, por precio o por posición, con la API. Para ver las gasolineras de una carretera, usa **`GET /v1/roads/{slug}/stations`**: devuelve las de la A-6, la AP-7, la N-340… con su punto kilométrico y su sentido cuando se conocen, ordenadas por precio o por posición. La lista de carreteras disponibles está en **`GET /v1/roads`**. ## 1. Elige la carretera [Sección titulada «1. Elige la carretera»](#1-elige-la-carretera) ```sh curl "https://api.preciosgasolina.es/v1/roads" ``` Devuelve las autovías, autopistas y nacionales con al menos 8 gasolineras localizadas. Cada una trae `slug` (`a-3`), `code` (`A-3`), `name`, `group`, `from`, `to`, `length_km` (puede ser `null`), `stations_indexed` y `web_url`. Esta respuesta se cachea 6 horas. Ejemplo ilustrativo ```json { "data": { "roads": [ { "slug": "a-3", "code": "A-3", "name": "Autovía del Este", "group": "radial", "from": "Madrid", "to": "Valencia", "length_km": 352, "stations_indexed": 31, "web_url": "https://preciosgasolina.es/gasolineras-carretera/a-3/" } ] }, "meta": { "…": "…" } } ``` ## 2. Pide sus gasolineras [Sección titulada «2. Pide sus gasolineras»](#2-pide-sus-gasolineras) Parámetros: `fuel` (por defecto `gasoline_95`), `sort` (`price`, por defecto, o `position`) y `limit` (1–50, por defecto 10). * curl ```sh # Las 10 gasolineras con el diésel más barato de la AP-7 curl "https://api.preciosgasolina.es/v1/roads/ap-7/stations?fuel=diesel&limit=10" # Las de la A-3 en orden de recorrido curl "https://api.preciosgasolina.es/v1/roads/a-3/stations?fuel=diesel&sort=position&limit=50" ``` * JavaScript ```js const res = await fetch("https://api.preciosgasolina.es/v1/roads/ap-7/stations?fuel=diesel&limit=10"); const body = await res.json(); if (!res.ok) throw new Error(`${body.code}: ${body.detail}`); // ROAD_NOT_FOUND si no hay datos for (const s of body.data.stations) { const pk = s.road_km != null ? `PK ${s.road_km}` : "PK desconocido"; console.log(`${s.price} €/L · ${s.name} · ${pk} · sentido ${s.side ?? "—"}${s.service_area ? " · área de servicio" : ""}`); } ``` * Python ```python import requests r = requests.get("https://api.preciosgasolina.es/v1/roads/ap-7/stations", params={"fuel": "diesel", "limit": 10}, timeout=10) body = r.json() if not r.ok: raise RuntimeError(f'{body["code"]}: {body["detail"]}') for s in body["data"]["stations"]: print(s["price"], s["name"], "PK", s.get("road_km"), s.get("side"), "área de servicio" if s.get("service_area") else "") ``` Además de los campos normales de una gasolinera, cada una trae: | Campo | Significado | | -------------- | ----------------------------------------------------------------------- | | `road_km` | Punto kilométrico aproximado, si se conoce. | | `side` | Lado de la carretera: `derecho`, `izquierdo` o `null` si no se sabe. | | `service_area` | `true` si está en un área de servicio. | | `position_km` | Posición a lo largo de la carretera (para ordenar con `sort=position`). | Nota La asignación de cada gasolinera a una carretera se calcula a partir de sus coordenadas y se actualiza de vez en cuando: una gasolinera muy nueva puede no aparecer todavía. Si una carretera no tiene datos (o tiene menos de 8 gasolineras localizadas), la API responde `404` con el código `ROAD_NOT_FOUND`. ## Con el servidor MCP [Sección titulada «Con el servidor MCP»](#con-el-servidor-mcp) `find_fuel_on_road` acepta el código o el slug de la carretera (`A-3`, `ap-7`), `fuel`, `sort` y `limit`. Ejemplo: «Gasolineras más baratas en la AP-7». Para un viaje que pasa por varias carreteras, usa [Dónde repostar en una ruta](/guias/repostar-en-una-ruta/). # Histórico de precios > Serie diaria de hasta 90 días por territorio o gasolinera, serie mensual de España desde 2005 e informes mensuales con la API de Gasolina hoy. La API tiene tres tipos de histórico: la **serie diaria** de un territorio (`GET /v1/history`) o de una gasolinera (`GET /v1/stations/{id}/history`), de hasta 90 días; la **serie mensual de España desde 2005** (`GET /v1/history/monthly`); y los **informes de cada mes cerrado** (`GET /v1/reports`). ## Serie diaria de un territorio [Sección titulada «Serie diaria de un territorio»](#serie-diaria-de-un-territorio) Parámetros: `fuel` (por defecto `gasoline_95`), `days` (1–90, por defecto 30) y, opcionalmente, `level` + `code` (sin ellos, España). * curl ```sh curl "https://api.preciosgasolina.es/v1/history?level=province&code=28&fuel=diesel&days=30" ``` * JavaScript ```js const res = await fetch("https://api.preciosgasolina.es/v1/history?" + new URLSearchParams({ level: "province", code: "28", fuel: "diesel", days: "30" })); const { data } = await res.json(); console.log(`${data.area.name}: ${data.change.pct} % entre ${data.change.from} y ${data.change.to}`); const serie = data.points.map((p) => [p.date, p.average]); // listo para una gráfica ``` * Python ```python import requests data = requests.get( "https://api.preciosgasolina.es/v1/history", params={"level": "province", "code": "28", "fuel": "diesel", "days": 30}, timeout=10, ).json()["data"] print(data["area"]["name"], data["change"]["pct"], "%") for p in data["points"]: print(p["date"], p["average"], p["minimum"], p["maximum"]) ``` Ejemplo ilustrativo: los valores no son precios reales ```json { "data": { "area": { "level": "province", "code": "28", "name": "Madrid", "web_url": "https://preciosgasolina.es/precios-gasolineras/comunidad-de-madrid/madrid/" }, "fuel": "diesel", "unit": "L", "currency": "EUR", "resolution": "day", "days": 3, "change": { "from": "2026-10-05", "to": "2026-10-07", "first_average": 1.47, "last_average": 1.474, "difference": 0.004, "pct": 0.27 }, "points": [ { "date": "2026-10-05", "average": 1.47, "minimum": 1.349, "maximum": 1.659 }, { "date": "2026-10-06", "average": 1.472, "minimum": 1.349, "maximum": 1.659 }, { "date": "2026-10-07", "average": 1.474, "minimum": 1.359, "maximum": 1.669 } ] }, "meta": { "…": "…" } } ``` ## Serie diaria de una gasolinera [Sección titulada «Serie diaria de una gasolinera»](#serie-diaria-de-una-gasolinera) `GET /v1/stations/{id}/history` devuelve el precio de cada día de los carburantes de una gasolinera (`id` del Ministerio o slug de su ficha). Con `fuel` te quedas con uno; `days` va de 1 a 90 (por defecto 30). ```sh curl "https://api.preciosgasolina.es/v1/stations/12345/history?fuel=diesel&days=60" ``` La respuesta trae la ficha de la gasolinera en `station` y una serie por carburante en `series[]` (`fuel`, `unit` y `points[]` con `date` y `price`). Consulta pesada El histórico de una gasolinera cuenta como **consulta pesada**: 30 por minuto por IP. Para muchas gasolineras a la vez, descarga los [datos abiertos](https://preciosgasolina.es/datos/) en lugar de pedirlas una a una. ## Serie mensual de España desde 2005 [Sección titulada «Serie mensual de España desde 2005»](#serie-mensual-de-españa-desde-2005) `GET /v1/history/monthly` devuelve las medias mensuales de la gasolina 95 y el gasóleo en España, **con y sin impuestos**, desde 2005. La fuente es el Boletín Petrolero de la Unión Europea (Weekly Oil Bulletin, Comisión Europea), no el Ministerio: no son los mismos datos que las medias diarias. Parámetros opcionales: `fuel` (`gasoline_95` o `diesel`), `from` y `to` en formato `AAAA-MM`. ```sh curl "https://api.preciosgasolina.es/v1/history/monthly?fuel=diesel&from=2022-01&to=2022-12" ``` Ejemplo ilustrativo: los valores no son precios reales ```json { "data": { "area": { "level": "spain", "code": "es", "name": "España" }, "resolution": "month", "currency": "EUR", "unit": "L", "source": { "name": "Boletín Petrolero de la Unión Europea (Weekly Oil Bulletin), Comisión Europea, DG ENER", "url": "https://energy.ec.europa.eu/data-and-analysis/weekly-oil-bulletin_en", "licence": "CC BY 4.0 (Decisión 2011/833/UE de la Comisión)" }, "note": "Medias mensuales del Boletín Petrolero de la UE (precio con impuestos y sin impuestos). No son los mismos datos que las medias diarias del Ministerio.", "series": [ { "fuel": "diesel", "points": [{ "month": "2022-01", "price": 1.401, "price_without_taxes": 0.802 }] } ] }, "meta": { "…": "…" } } ``` ## Informes mensuales [Sección titulada «Informes mensuales»](#informes-mensuales) * `GET /v1/reports`: meses cerrados con informe y la media de España de cada mes. * `GET /v1/reports/{month}` (`AAAA-MM`): medias del mes, días más baratos y más caros y provincias ordenadas por precio. Solo hay informes de meses cerrados: pedir el mes en curso devuelve `400`. ```sh curl "https://api.preciosgasolina.es/v1/reports/2026-09" ``` ## Con el servidor MCP [Sección titulada «Con el servidor MCP»](#con-el-servidor-mcp) `get_price_history` cubre los tres casos: territorio (`level` + `code`), gasolinera (`station_id`) y serie mensual (`monthly=true`, con `from`). Ejemplo: «¿Cuánto ha subido el diésel este mes?». Los informes, con `get_monthly_report`: «¿Cómo fueron los precios en septiembre?». # Integrar en tu web o app > CORS, caché hasta meta.next_update, atribución, errores y reintentos con Retry-After: cómo integrar la API de Gasolina hoy en producción, con código. Esta guía reúne lo necesario para usar la API en producción: llamarla desde el navegador (CORS), **cachear hasta la próxima actualización** con `meta.next_update`, mostrar la atribución y **reintentar bien** cuando la API pide esperar (`429` o `503` con `Retry-After`). ## Desde el navegador o desde tu servidor [Sección titulada «Desde el navegador o desde tu servidor»](#desde-el-navegador-o-desde-tu-servidor) La API admite **CORS desde cualquier origen** (`Access-Control-Allow-Origin: *`, sin credenciales ni cookies), así que puedes llamarla directamente con `fetch` desde una página web. Los límites son **por IP**: si la llaman tus usuarios desde su navegador, cada uno tiene su cuota. Si tu servidor hace las peticiones para muchos usuarios (una app con backend, un bot), todas salen de la misma IP y comparten los [límites](/conceptos/limites/): en ese caso **cachea en tu servidor** y sirve desde ahí. Las cabeceras que puedes leer desde JavaScript en otro origen son `RateLimit-Policy`, `Retry-After` y `X-Request-Id` (además de las simples, como `Content-Type` y `Cache-Control`). ## Cachea hasta `meta.next_update` [Sección titulada «Cachea hasta meta.next_update»](#cachea-hasta-metanext_update) Los precios solo cambian dos veces al día (hacia las 8:00 y las 20:00, hora peninsular). Cada respuesta dice cuándo llegarán datos nuevos en `meta.next_update`, y las respuestas con precios llevan `Cache-Control: public, max-age=…` hasta esa hora (como mucho una hora, con `stale-while-revalidate=300`). Pedir lo mismo antes no te dará datos distintos. 1. Guarda cada respuesta con la clave de su URL. 2. Sírvela desde tu caché mientras la hora actual sea anterior a `meta.next_update` (más un margen de unos minutos, porque la actualización tarda en completarse). 3. Después, vuelve a pedirla. Si `meta.last_updated` no ha cambiado, la actualización aún no ha terminado: reintenta en unos minutos. ## Un cliente completo [Sección titulada «Un cliente completo»](#un-cliente-completo) Con caché hasta `next_update`, reintentos con `Retry-After` y errores RFC 9457: * JavaScript ```js const API = "https://api.preciosgasolina.es/v1"; const cache = new Map(); // url → { body, until } const MARGEN_MS = 10 * 60 * 1000; // la actualización tarda unos minutos const sleep = (ms) => new Promise((r) => setTimeout(r, ms)); export class ApiError extends Error { constructor(problem) { super(`${problem.code}: ${problem.detail}`); Object.assign(this, problem); // type, title, status, detail, code, request_id, instance } } export async function api(path, params = {}, { intentos = 3 } = {}) { const url = API + path + (Object.keys(params).length ? "?" + new URLSearchParams(params) : ""); const hit = cache.get(url); if (hit && Date.now() < hit.until) return hit.body; for (let i = 1; ; i++) { const res = await fetch(url, { headers: { Accept: "application/json" }, signal: AbortSignal.timeout(10_000) }); if (res.ok) { const body = await res.json(); const next = Date.parse(body.meta?.next_update); // Hasta la próxima actualización (+ margen); si no hay fecha, 10 minutos. const until = Number.isFinite(next) ? next + MARGEN_MS : Date.now() + MARGEN_MS; cache.set(url, { body, until }); return body; } const problem = await res.json().catch(() => ({ status: res.status, code: "HTTP_" + res.status, detail: res.statusText })); // Solo se reintenta lo que es temporal: 429 y 503 (con Retry-After) y errores 5xx. const temporal = res.status === 429 || res.status >= 500; if (!temporal || i >= intentos) { if (hit) return hit.body; // mejor un dato de la actualización anterior que nada throw new ApiError(problem); } const retryAfter = Number(res.headers.get("Retry-After")); await sleep((Number.isFinite(retryAfter) && retryAfter > 0 ? retryAfter : 2 ** i) * 1000); } } // Uso const { data, meta } = await api("/prices", { level: "province", code: "28" }); ``` * Python ```python import time from datetime import datetime, timezone import requests API = "https://api.preciosgasolina.es/v1" MARGEN_S = 600 # la actualización tarda unos minutos _cache: dict[str, tuple[float, dict]] = {} _s = requests.Session() _s.headers["Accept"] = "application/json" class ApiError(Exception): def __init__(self, problem: dict): super().__init__(f'{problem.get("code")}: {problem.get("detail")}') self.problem = problem # type, title, status, detail, code, request_id, instance def api(path: str, intentos: int = 3, **params) -> dict: key = path + "?" + "&".join(f"{k}={v}" for k, v in sorted(params.items())) hit = _cache.get(key) if hit and time.time() < hit[0]: return hit[1] for i in range(1, intentos + 1): r = _s.get(API + path, params=params, timeout=10) if r.ok: body = r.json() nxt = body.get("meta", {}).get("next_update") until = datetime.fromisoformat(nxt.replace("Z", "+00:00")).timestamp() + MARGEN_S if nxt else time.time() + MARGEN_S _cache[key] = (until, body) return body temporal = r.status_code == 429 or r.status_code >= 500 if not temporal or i == intentos: if hit: return hit[1] # mejor la actualización anterior que nada try: raise ApiError(r.json()) except ValueError: raise ApiError({"status": r.status_code, "code": f"HTTP_{r.status_code}", "detail": r.reason}) retry_after = r.headers.get("Retry-After") time.sleep(int(retry_after) if retry_after and retry_after.isdigit() else 2**i) raise RuntimeError("inalcanzable") body = api("/prices", level="province", code="28") ``` No reintentes los errores 4xx Un `400` (parámetro mal escrito), un `404` (no existe) o un `405` no se arreglan reintentando: corrige la petición. Solo `429` y `503` llevan `Retry-After`; respeta ese tiempo antes de volver a intentarlo. Más en [Errores](/conceptos/errores/). ## Muestra la fuente y la fecha [Sección titulada «Muestra la fuente y la fecha»](#muestra-la-fuente-y-la-fecha) Debajo de los datos, muestra `meta.attribution`, la fecha de `meta.last_updated` en hora de Madrid y un enlace a `meta.web_url`. Es la condición de la licencia CC BY 4.0: [Atribución y licencia](/empezar/atribucion-y-licencia/). ## `meta.stale`: datos de la actualización anterior [Sección titulada «meta.stale: datos de la actualización anterior»](#metastale-datos-de-la-actualización-anterior) Si la base de datos no responde, la API sirve la última copia buena de esa respuesta con `meta.stale: true` y `Cache-Control: public, max-age=60`. Los datos son correctos pero pueden ser de la actualización anterior: puedes mostrarlos con la fecha de `meta.last_updated` y volver a pedirlos en un minuto. Ver [Frescura de los datos](/conceptos/frescura/). ## Lista de comprobación [Sección titulada «Lista de comprobación»](#lista-de-comprobación) * [ ] Cacheas cada respuesta hasta `meta.next_update`. * [ ] Muestras `meta.attribution`, la fecha de los datos y un enlace a `meta.web_url`. * [ ] Reintentas solo `429`, `503` y otros `5xx`, respetando `Retry-After`. * [ ] Guardas `request_id` en tus registros de error (y nos lo envías si nos escribes por un fallo). * [ ] Usas `limit` (máximo 50) y no recorres toda España petición a petición: para eso están los [datos abiertos](https://preciosgasolina.es/datos/). * [ ] No pides parámetros que el endpoint no admite: la API responde `400` a los parámetros desconocidos. # Las más baratas de una provincia > Lista las gasolineras más baratas y el precio medio de hoy de una provincia, comunidad o municipio, y compara provincias con la API de Gasolina hoy. Para las gasolineras más baratas de un territorio, usa **`GET /v1/stations/cheapest`** con `level` y `code`. Para su precio medio frente a España, **`GET /v1/prices`**. Y para saber qué provincias o comunidades son más baratas, **`GET /v1/rankings/regions`**. ## Las más baratas de un territorio [Sección titulada «Las más baratas de un territorio»](#las-más-baratas-de-un-territorio) `level` puede ser `community`, `province` o `municipality`; `code` es el código INE (o el slug) de la comunidad o provincia, o el id de municipio de la API (ver [Conceptos básicos](/empezar/conceptos-basicos/)). * curl ```sh # Las 10 gasolineras con la gasolina 95 más barata de la provincia de Valencia curl "https://api.preciosgasolina.es/v1/stations/cheapest?fuel=gasoline_95&level=province&code=46&limit=10" ``` * JavaScript ```js const API = "https://api.preciosgasolina.es/v1"; async function get(path, params) { const res = await fetch(API + path + "?" + new URLSearchParams(params)); const body = await res.json(); if (!res.ok) throw new Error(`${body.code}: ${body.detail}`); return body; } const { data } = await get("/stations/cheapest", { fuel: "gasoline_95", level: "province", code: "46", limit: "10" }); console.log(data.area.name); data.stations.forEach((s, i) => console.log(i + 1, s.price.toFixed(3), s.name, s.municipality.name)); ``` * Python ```python import requests API = "https://api.preciosgasolina.es/v1" def get(path, **params): r = requests.get(API + path, params=params, timeout=10) body = r.json() if not r.ok: raise RuntimeError(f'{body["code"]}: {body["detail"]}') return body data = get("/stations/cheapest", fuel="gasoline_95", level="province", code="46", limit=10)["data"] print(data["area"]["name"]) for i, s in enumerate(data["stations"], 1): print(i, f'{s["price"]:.3f}', s["name"], s["municipality"]["name"]) ``` Filtros opcionales: `open_24h=true` y `brand=`. Sin `level` (o con `level=spain`) obtienes las más baratas de España; en ese caso Canarias, Ceuta y Melilla van aparte (no pagan el Impuesto sobre Hidrocarburos) salvo que añadas `include_low_tax=true`, y `data.note` lo indica. ## Precio medio de hoy [Sección titulada «Precio medio de hoy»](#precio-medio-de-hoy) `GET /v1/prices` devuelve, para cada carburante, la media, la mediana, el mínimo, el máximo, el número de gasolineras, la variación frente al día anterior (en %) y la diferencia con la media de España (en %). Con `fuel` te quedas con uno solo. ```sh curl "https://api.preciosgasolina.es/v1/prices?level=province&code=46&fuel=diesel" ``` Ejemplo ilustrativo: los valores no son precios reales ```json { "data": { "area": { "level": "province", "code": "46", "name": "Valencia", "web_url": "https://preciosgasolina.es/precios-gasolineras/comunitat-valenciana/valencia/" }, "stations": 612, "currency": "EUR", "fuels": [ { "fuel": "diesel", "label": "Gasóleo A (diésel)", "unit": "L", "average": 1.462, "median": 1.469, "minimum": 1.329, "maximum": 1.629, "stations": 598, "change_vs_previous_day_pct": -0.2, "spain_average": 1.481, "vs_spain_pct": -1.28, "cheapest_station_id": 12345, "fuel_page_url": "https://preciosgasolina.es/precio-diesel/" } ] }, "meta": { "…": "…" } } ``` `cheapest_station_id` es el `id` de la gasolinera más barata: pídela con `GET /v1/stations/{id}` para ver su ficha completa. ## Comparar provincias o comunidades [Sección titulada «Comparar provincias o comunidades»](#comparar-provincias-o-comunidades) `GET /v1/rankings/regions` ordena las provincias (`level=province`, por defecto) o las comunidades (`level=community`) de más barata a más cara para un carburante (`fuel`, por defecto `diesel`): ```sh curl "https://api.preciosgasolina.es/v1/rankings/regions?level=community&fuel=gasoline_95" ``` Cada fila trae `rank`, `code`, `name`, `average`, `minimum`, `maximum`, `stations`, `vs_spain_pct`, `low_tax_area` y `web_url`. Canarias, Ceuta y Melilla se excluyen salvo `include_low_tax=true`. Cachea hasta la próxima actualización Estas respuestas solo cambian cuando hay datos nuevos (dos veces al día). Guárdalas hasta `meta.next_update` en lugar de repetir la petición: ver [Integrar en tu web](/guias/integrar-en-tu-web/). ## Con el servidor MCP [Sección titulada «Con el servidor MCP»](#con-el-servidor-mcp) * `find_cheapest_fuel` con `level` y `code`: «Diésel más barato en Sevilla». * `get_fuel_prices`: «Precio medio de la gasolina en Valencia hoy frente a España». * `compare_regions`: «¿Qué provincia tiene el diésel más barato?». # Dónde repostar en una ruta > Envía tu ruta a POST /v1/route/fuel y obtén las gasolineras más baratas del recorrido y el coste del viaje, o usa las rutas del catálogo de Gasolina hoy. Para saber dónde repostar más barato en un viaje, envía los puntos de tu ruta a **`POST /v1/route/fuel`**: la API devuelve las gasolineras más baratas a menos de `corridor_km` del recorrido, su posición en la ruta y el coste estimado del viaje. Si quieres rutas ya preparadas (en coche o en moto), usa el catálogo: **`GET /v1/routes`** y **`GET /v1/routes/{slug}`**. ## Tu propia ruta: `POST /v1/route/fuel` [Sección titulada «Tu propia ruta: POST /v1/route/fuel»](#tu-propia-ruta-post-v1routefuel) Es el único endpoint de la API que usa `POST`, porque la ruta no cabe en una URL. El cuerpo es JSON (`Content-Type: application/json`, 32 KB como mucho): | Campo | Tipo | Obligatorio | Descripción | | ------------- | ----------------- | ----------- | ----------------------------------------------------------------------------------- | | `points` | `[[lat, lng], …]` | sí | De 2 a 200 puntos en orden de recorrido (origen, localidades intermedias, destino). | | `fuel` | texto | no | Carburante (por defecto `gasoline_95`). | | `corridor_km` | número | no | Distancia máxima a la ruta, de más de 0 a 10 km (por defecto 3). | | `limit` | entero | no | De 1 a 50 gasolineras (por defecto 10). | | `open_24h` | booleano | no | Solo las abiertas 24 horas. | | `consumption` | número | no | Consumo en L/100 km (kg/100 km con GNC), hasta 40, para estimar el coste. | La ruta puede medir hasta **1.500 km**; si es más larga, la API responde `400`. Las distancias se calculan en línea recta entre los puntos que envías: **cuantos más puntos, más preciso** (por ejemplo, uno cada 10–20 km de tu polilínea). 1. **Consigue la polilínea.** De tu servicio de rutas o de tu mapa, como lista de pares `[lat, lng]`. Si tienes muchos puntos, quédate con 200 como mucho repartidos por el recorrido. 2. **Envíala.** * curl ```sh curl -X POST "https://api.preciosgasolina.es/v1/route/fuel" \ -H "Content-Type: application/json" \ -d '{ "points": [[40.4168, -3.7038], [40.0704, -2.1374], [39.4699, -0.3763]], "fuel": "diesel", "corridor_km": 3, "limit": 5, "consumption": 6 }' ``` * JavaScript ```js // Reduce una polilínea larga a 200 puntos como mucho, conservando el primero y el último. function simplificar(puntos, max = 200) { if (puntos.length <= max) return puntos; const paso = (puntos.length - 1) / (max - 1); return Array.from({ length: max }, (_, i) => puntos[Math.round(i * paso)]); } const res = await fetch("https://api.preciosgasolina.es/v1/route/fuel", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ points: simplificar(miPolilinea), // [[lat, lng], …] fuel: "diesel", corridor_km: 3, limit: 5, consumption: 6, }), }); const body = await res.json(); if (!res.ok) throw new Error(`${body.code}: ${body.detail}`); const { route_length_km, trip_estimate, stations } = body.data; console.log(`${route_length_km} km · ${trip_estimate?.cost_eur} € con la media de hoy`); for (const s of stations) console.log(`km ${s.position_km}: ${s.price} €/L · ${s.name} (a ${s.distance_to_route_km} km)`); ``` * Python ```python import requests ruta = [[40.4168, -3.7038], [40.0704, -2.1374], [39.4699, -0.3763]] r = requests.post( "https://api.preciosgasolina.es/v1/route/fuel", json={"points": ruta, "fuel": "diesel", "corridor_km": 3, "limit": 5, "consumption": 6}, timeout=15, ) body = r.json() if not r.ok: raise RuntimeError(f'{body["code"]}: {body["detail"]}') d = body["data"] print(d["route_length_km"], "km ·", (d["trip_estimate"] or {}).get("cost_eur"), "€") for s in d["stations"]: print("km", s["position_km"], s["price"], s["name"], "a", s["distance_to_route_km"], "km") ``` 3. **Muestra las paradas** ordenadas por `position_km` (kilómetros desde el origen) o por precio, con la fecha de los datos y la [atribución](/empezar/atribucion-y-licencia/). Ejemplo ilustrativo: los valores no son precios reales ```json { "data": { "fuel": "diesel", "currency": "EUR", "route_length_km": 302.6, "corridor_km": 3, "trip_estimate": { "consumption_per_100km": 6, "price_used": 1.481, "price_basis": "media de España de hoy", "fuel_quantity": 18.2, "cost_eur": 26.95, "cost_at_cheapest_on_route_eur": 25.28 }, "note": "Distancias en línea recta entre los puntos enviados: cuantos más puntos, más preciso.", "stations": [ { "id": 12345, "name": "Estación de ejemplo", "brand": { "slug": "marca-ejemplo", "name": "Marca Ejemplo" }, "address": "Calle de Ejemplo, 1", "postal_code": "16001", "municipality": { "id": 1234, "name": "Municipio de ejemplo" }, "province": { "code": "16", "name": "Cuenca" }, "community": { "code": "08", "name": "Castilla-La Mancha" }, "lat": 40.07, "lng": -2.14, "is_24h": true, "hours": "L-D: 24H", "low_tax_area": false, "web_url": "https://preciosgasolina.es/gasolineras/estacion-de-ejemplo-12345/", "price": 1.389, "price_updated_at": "2026-10-07T06:12:00.000+00:00", "distance_to_route_km": 0.8, "position_km": 141.2 } ] }, "meta": { "web_url": "https://preciosgasolina.es/herramientas/calculadora-ruta/", "…": "…" } } ``` `trip_estimate` usa la media de España de hoy del carburante (y, si no indicas `consumption`, un consumo típico); `cost_at_cheapest_on_route_eur` es el coste si repostas todo en la gasolinera más barata del recorrido. Puede ser `null` si no hay precio medio. Límites `POST /v1/route/fuel` cuenta como **consulta pesada** (30 por minuto por IP) y no se cachea. Las coordenadas se redondean a 3 decimales. Los campos desconocidos en el cuerpo devuelven `400` (`INVALID_PARAMETER`), un JSON mal formado `400` (`INVALID_JSON`), un cuerpo de más de 32 KB `413` y otro tipo de contenido `415`. Ver [Errores](/conceptos/errores/). ## Rutas del catálogo [Sección titulada «Rutas del catálogo»](#rutas-del-catálogo) preciosgasolina.es tiene un catálogo de rutas por carretera en coche y en moto. `GET /v1/routes` las busca: | Parámetro | Valores | | --------- | -------------------------------------------------- | | `type` | `moto`, `rurales`, `costa`, `montana` o `clasicas` | | `region` | nombre de una comunidad (p. ej. `Andalucía`) | | `q` | texto libre (2–100 caracteres) | | `limit` | 1–50 (por defecto 20) | ```sh curl "https://api.preciosgasolina.es/v1/routes?type=costa®ion=Andalucía&limit=5" ``` Cada ruta trae `slug`, `title`, `description`, `answer` (resumen), `tags` y `web_url`. Con el slug, `GET /v1/routes/{slug}` devuelve el recorrido completo (localidades con coordenadas, distancia, duración, dificultad, mejor temporada, puntos destacados y fotos con su autor y licencia), el coste estimado del viaje (`trip_estimate`) y las gasolineras más baratas a 3 km o menos del trazado (`stations_along`): ```sh curl "https://api.preciosgasolina.es/v1/routes/albufera-cullera-gandia-denia-en-coche?fuel=diesel&limit=5&consumption=6.5" ``` `GET /v1/routes/{slug}` también es una consulta pesada. El trazado de las rutas del catálogo es aproximado (une sus localidades). ## Con el servidor MCP [Sección titulada «Con el servidor MCP»](#con-el-servidor-mcp) `find_fuel_along_route` hace lo mismo que `POST /v1/route/fuel` («Voy de Madrid a Valencia por la A-3, ¿dónde reposto?»); `find_routes` y `get_route`, lo mismo que el catálogo. El prompt `planificar_viaje` combina el coste, las paradas y una ruta del catálogo. # Servidor MCP > Qué es el servidor MCP de Gasolina hoy: URL, Streamable HTTP sin estado ni inicio de sesión, 21 herramientas de solo lectura, recursos, prompts y límites. El **servidor MCP** de Gasolina hoy permite que un asistente de IA (Claude, ChatGPT, Cursor, VS Code, Claude Code o cualquier cliente compatible con el [Model Context Protocol](https://modelcontextprotocol.io/)) consulte los precios oficiales de los carburantes de España: gasolineras más baratas, precios medios, histórico, carreteras, rutas, guías y calculadoras. Es gratuito, de solo lectura y no necesita iniciar sesión. ## Dirección [Sección titulada «Dirección»](#dirección) ```text https://mcp.preciosgasolina.es/mcp ``` | | | | ------------------- | -------------------------------------------------------------------------------------------------------------------------------- | | Transporte | Streamable HTTP, **sin estado**: cada mensaje es una petición `POST` independiente, con respuesta JSON (sin flujos SSE abiertos) | | Autenticación | Ninguna (no hay inicio de sesión ni clave) | | Sesiones | No se usan (no se emite `Mcp-Session-Id`) | | Lotes JSON-RPC | No se admiten: un mensaje por petición | | Capacidades | `tools` (21 herramientas), `resources` (3 recursos y 3 plantillas) y `prompts` (4) | | Nombre del servidor | `preciosgasolina` (versión 1.0.0) | Una petición `GET` a `/mcp` responde `405`: el servidor no abre flujos de eventos. Si el cliente envía la cabecera `Origin`, debe ser `https://` (o `localhost` en desarrollo). ## Qué incluye [Sección titulada «Qué incluye»](#qué-incluye) * **21 herramientas** en cuatro grupos: precios y gasolineras, carreteras y rutas, contenido y calculadoras. Todas son de solo lectura (`readOnlyHint: true`, `destructiveHint: false`, `idempotentHint: true`). Lista completa con sus argumentos: [Herramientas](/mcp/herramientas/). * **Recursos**: tipos de carburante, territorios con sus códigos INE, metodología y plantillas para leer guías, artículos y rutas. **Prompts**: planificar un viaje, repostar barato cerca, entender el precio y comparar marcas. Ver [Recursos y prompts](/mcp/recursos-y-prompts/). * **Instrucciones del servidor** (las recibe el modelo al conectarse): los precios son los comunicados al Ministerio y se actualizan dos veces al día, no en tiempo real; hay que citar la fecha (`meta.last_updated`), mostrar la atribución y enlazar `meta.web_url`; y conviene usar `search_places` primero para convertir nombres en identificadores. Cada resultado de herramienta lleva el mismo `meta` que la API REST (fecha, próxima actualización, fuente, atribución, licencia y `web_url`) dentro de `structuredContent`, y el mismo JSON como texto en `content`. ## Probarlo con curl [Sección titulada «Probarlo con curl»](#probarlo-con-curl) El servidor responde a cualquier cliente que hable JSON-RPC por HTTP. Por ejemplo, el saludo inicial: ```sh curl -X POST "https://mcp.preciosgasolina.es/mcp" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-06-18","capabilities":{},"clientInfo":{"name":"curl","version":"1"}}}' ``` Y una llamada a una herramienta: ```sh curl -X POST "https://mcp.preciosgasolina.es/mcp" \ -H "Content-Type: application/json" \ -H "Accept: application/json, text/event-stream" \ -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"get_fuel_prices","arguments":{"level":"province","code":"28","fuel":"diesel"}}}' ``` Ejemplo ilustrativo: los valores no son precios reales ```json { "result": { "content": [{ "type": "text", "text": "{\"data\":{…},\"meta\":{…}}" }], "structuredContent": { "data": { "area": { "level": "province", "code": "28", "name": "Madrid", "web_url": "https://preciosgasolina.es/precios-gasolineras/comunidad-de-madrid/madrid/" }, "stations": 812, "currency": "EUR", "fuels": [{ "fuel": "diesel", "label": "Gasóleo A (diésel)", "unit": "L", "average": 1.474, "median": 1.479, "minimum": 1.349, "maximum": 1.689, "stations": 801, "change_vs_previous_day_pct": 0.1, "spain_average": 1.481, "vs_spain_pct": -0.47, "cheapest_station_id": 12345, "fuel_page_url": "https://preciosgasolina.es/precio-diesel/" }] }, "meta": { "api_version": "v1", "request_id": "ef949c7354ab4109", "last_updated": "2026-10-07T06:12:00.000Z", "next_update": "2026-10-07T18:10:00.000Z", "data_age_seconds": 7476, "stale": false, "source": "Ministerio para la Transición Ecológica y el Reto Demográfico (Geoportal de Gasolineras)", "attribution": "Fuente: Gasolina hoy (preciosgasolina.es), con datos del Ministerio para la Transición Ecológica y el Reto Demográfico (Geoportal de Gasolineras).", "license": "https://creativecommons.org/licenses/by/4.0/", "web_url": "https://preciosgasolina.es/precios-gasolineras/comunidad-de-madrid/madrid/" } } }, "jsonrpc": "2.0", "id": 2 } ``` ## Límites y tamaños [Sección titulada «Límites y tamaños»](#límites-y-tamaños) | | | | ---------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | | Mensajes por minuto y por IP | 60 | | Llamadas a herramientas (`tools/call`) por minuto y por IP | 30 | | Tamaño máximo de un mensaje | 64 KB | | Tamaño de cada resultado | unos 20 KB: si se supera, las listas largas se recortan a 10 elementos, los textos largos a 12.000 caracteres y el resultado lleva `truncated: true` | Al superar un límite, el servidor responde `429` con `Retry-After: 60` y un error JSON-RPC. Si una herramienta falla (por ejemplo, un código de provincia que no existe), el resultado lleva `isError: true` y un texto con el código del error (`PROVINCE_NOT_FOUND: …`). Más en [Límites de uso](/conceptos/limites/). ¿API REST o MCP? Usa el **MCP** si un modelo de lenguaje decide qué consultar (asistentes, agentes). Usa la **[API REST](/referencia/)** si tu código sabe exactamente qué pedir (webs, apps, scripts): tiene más endpoints, caché HTTP y límites más amplios. Las dos usan los mismos datos y la misma caché. ## Siguientes pasos [Sección titulada «Siguientes pasos»](#siguientes-pasos) [Conectar el servidor](/mcp/conectar/)Claude, ChatGPT, Cursor, VS Code y Claude Code. [Herramientas](/mcp/herramientas/)Las 21 herramientas con sus argumentos y preguntas de ejemplo. [Recursos y prompts](/mcp/recursos-y-prompts/)Datos de referencia y plantillas de conversación. [Buenas prácticas](/mcp/buenas-practicas/)Para quien construye agentes con estos datos. # Buenas prácticas para agentes > Cómo construir agentes con el MCP de Gasolina hoy: citar fecha y web_url, usar search_places primero, respetar límites y no hablar de tiempo real. Si construyes un agente, un bot o una integración que usa el servidor MCP (o la API REST desde un modelo de lenguaje), estas pautas hacen que sus respuestas sean correctas, verificables y respetuosas con el servicio. El servidor ya envía un resumen de ellas como instrucciones al conectarse. ## 1. Los precios no son en tiempo real [Sección titulada «1. Los precios no son en tiempo real»](#1-los-precios-no-son-en-tiempo-real) Los precios son los que las gasolineras comunican al Ministerio y se actualizan **dos veces al día** (hacia las 8:00 y las 20:00, hora peninsular). El precio del surtidor puede haber cambiado desde entonces. * Di siempre de cuándo son los datos, con `meta.last_updated` convertido a hora de Madrid: «según los datos del Ministerio de hoy a las 8:12…». * No escribas «ahora», «en este momento» ni «en tiempo real». * Si `meta.stale` es `true`, los datos pueden ser de la actualización anterior: menciónalo. ## 2. Cita la fuente y enlaza [Sección titulada «2. Cita la fuente y enlaza»](#2-cita-la-fuente-y-enlaza) Cada resultado trae `meta.attribution` y `meta.web_url`. Incluye en la respuesta la fuente (Gasolina hoy, con datos del Ministerio para la Transición Ecológica y el Reto Demográfico) y el enlace a `web_url`; para gasolineras concretas, el `web_url` de cada una. Es la condición de la licencia CC BY 4.0 y permite al usuario comprobar el dato ([Atribución y licencia](/empezar/atribucion-y-licencia/)). ## 3. Primero `search_places` [Sección titulada «3. Primero search_places»](#3-primero-search_places) Los nombres son ambiguos («Valencia» es una ciudad, una provincia y una comunidad; «Santiago» hay varios). Antes de pedir precios de un lugar que el usuario ha nombrado, llama a `search_places` y usa el `level` y el `code` (o el `station_id`) del resultado. No inventes códigos: el `code` de un municipio no es su código INE. ## 4. Elige la herramienta más concreta [Sección titulada «4. Elige la herramienta más concreta»](#4-elige-la-herramienta-más-concreta) | El usuario pregunta por… | Herramienta | | ---------------------------- | ------------------------------------------------------------------------ | | Lo más barato en un sitio | `find_cheapest_fuel` (con `level` + `code`, o con `lat` + `lng`) | | Lo más cercano a un punto | `find_fuel_near` con `sort: "distance"` | | Un viaje de A a B | `find_fuel_along_route` (con puntos intermedios) y `calculate_trip_cost` | | Una autovía concreta | `find_fuel_on_road` | | Una media o una comparación | `get_fuel_prices`, `compare_regions`, `compare_brands` | | La evolución | `get_price_history`, `get_monthly_report` | | Una duda («¿qué es el E10?») | `search_content` y, si hace falta, `get_article` | | Impuestos | `explain_fuel_price` | ## 5. Respeta los límites [Sección titulada «5. Respeta los límites»](#5-respeta-los-límites) * Como mucho **30 llamadas a herramientas por minuto** (y 60 mensajes) por IP. Un agente no necesita más para una conversación. * No recorras España provincia a provincia: `compare_regions` ya da el ranking completo en una llamada. * Pide solo los resultados que vas a usar (`limit`), no 50 si vas a mostrar 5. * Si recibes `429`, espera lo que indique `Retry-After` (60 segundos) antes de volver a intentarlo. * Para análisis masivos, usa los [datos abiertos](https://preciosgasolina.es/datos/), no el MCP. Detalles en [Límites de uso](/conceptos/limites/). ## 6. Canarias, Ceuta y Melilla [Sección titulada «6. Canarias, Ceuta y Melilla»](#6-canarias-ceuta-y-melilla) No pagan el Impuesto sobre Hidrocarburos: sus precios son más bajos por fiscalidad, no por la gasolinera. En los rankings de toda España van aparte salvo `include_low_tax: true`. Si el usuario está allí, busca dentro de su territorio; si compara con la península, explícalo. ## 7. No opines sobre marcas ni gasolineras [Sección titulada «7. No opines sobre marcas ni gasolineras»](#7-no-opines-sobre-marcas-ni-gasolineras) Los datos son del Ministerio: compara precios y calcula diferencias, pero no valores calidad ni recomiendes marcas sin datos. Los hechos de cada marca (`compare_brands` con `brands`) llevan sus fuentes: cítalas. ## 8. Resultados recortados y errores [Sección titulada «8. Resultados recortados y errores»](#8-resultados-recortados-y-errores) * Si un resultado trae `truncated: true`, las listas se han recortado a 10 elementos para no saturar el contexto: pide menos (`limit`) o filtra más. * Si una herramienta devuelve `isError: true`, lee el código (`PROVINCE_NOT_FOUND`, `INVALID_PARAMETER`…) y corrige los argumentos; no repitas la misma llamada. Ver [Errores](/conceptos/errores/). Ejemplo de respuesta bien hecha «El diésel más barato de la provincia de Madrid está hoy en la Estación de ejemplo (Calle de Ejemplo, 1, Getafe), a 1,389 €/L, según los datos del Ministerio actualizados hoy a las 8:12. Fuente: Gasolina hoy (preciosgasolina.es), con datos del Ministerio para la Transición Ecológica y el Reto Demográfico. Ficha: [https://preciosgasolina.es/gasolineras/…»](https://preciosgasolina.es/gasolineras/%E2%80%A6%C2%BB)\ *(Ejemplo ilustrativo: los valores no son precios reales.)* # Conectar el servidor MCP > Cómo añadir el servidor MCP de Gasolina hoy en Claude, ChatGPT, Cursor, VS Code y Claude Code, paso a paso y sin iniciar sesión. Para usar los datos de Gasolina hoy en tu asistente de IA, añade este servidor MCP. No hace falta cuenta, clave ni inicio de sesión: ```text https://mcp.preciosgasolina.es/mcp ``` Los menús cambian Los clientes de IA renombran y reorganizan sus menús a menudo. Si no encuentras una opción con el nombre exacto, busca «conectores», «MCP» o «aplicaciones» en la configuración. Los nombres entre paréntesis son los de la interfaz en inglés. ## Claude (web y escritorio) [Sección titulada «Claude (web y escritorio)»](#claude-web-y-escritorio) 1. En Claude (web o escritorio; planes Free, Pro y Max), abre Personalizar (Customize) > Conectores (Connectors). 2. Pulsa «Añadir conector personalizado» (Add custom connector) y pega la dirección https\://mcp.preciosgasolina.es/mcp. 3. Pulsa «Añadir» (Add). No hace falta iniciar sesión. 4. En cada chat, actívalo desde el botón «+» > Conectores (Connectors). En los planes Team y Enterprise, la persona propietaria de la organización lo añade en Configuración de la organización > Conectores (Organization settings > Connectors). ## ChatGPT [Sección titulada «ChatGPT»](#chatgpt) 1. En ChatGPT (web; planes Plus, Pro, Business, Enterprise y Education), abre Configuración (Settings) > Aplicaciones (Apps) > Configuración avanzada (Advanced settings) y activa el modo desarrollador (Developer mode). 2. Crea la aplicación con la dirección https\://mcp.preciosgasolina.es/mcp y sin autenticación. 3. En el chat, actívala desde el botón «+». OpenAI está cambiando el nombre de algunos menús: los nombres pueden variar. ## Claude Code [Sección titulada «Claude Code»](#claude-code) Ejecuta en tu terminal: ```sh claude mcp add --transport http preciosgasolina https://mcp.preciosgasolina.es/mcp ``` Comprueba que aparece con `claude mcp list` y pregunta, por ejemplo, «¿cuál es la gasolinera más barata de la A-3?». ## Cursor [Sección titulada «Cursor»](#cursor) Añade el servidor a `.cursor/mcp.json` en tu proyecto (o a `~/.cursor/mcp.json` para todos tus proyectos): .cursor/mcp.json ```json { "mcpServers": { "preciosgasolina": { "url": "https://mcp.preciosgasolina.es/mcp" } } } ``` ## VS Code [Sección titulada «VS Code»](#vs-code) Añade el servidor a `.vscode/mcp.json` en tu proyecto (o a la configuración MCP de tu perfil de usuario): .vscode/mcp.json ```json { "servers": { "preciosgasolina": { "type": "http", "url": "https://mcp.preciosgasolina.es/mcp" } } } ``` Después, abre el chat en modo agente y activa las herramientas de `preciosgasolina`. ## Otros clientes [Sección titulada «Otros clientes»](#otros-clientes) Cualquier cliente compatible con MCP por HTTP («Streamable HTTP») puede usarlo con la dirección de arriba y sin autenticación. Si tu cliente solo admite servidores locales por `stdio`, necesitarás un adaptador que reenvíe a un servidor remoto por HTTP. ## Comprueba que funciona [Sección titulada «Comprueba que funciona»](#comprueba-que-funciona) Abre un chat nuevo, activa el conector si tu cliente lo pide y prueba alguna de estas preguntas: * «¿Qué provincia tiene el diésel más barato hoy?» * «Gasolineras más baratas en la AP-7» * «¿Cuánto me cuesta ir de Madrid a Valencia con 6,5 L/100 km?» * «¿Cuánto de un litro son impuestos con la rebaja?» La respuesta debería citar la fecha de los datos y enlazar preciosgasolina.es. Si el asistente no usa las herramientas, pídeselo de forma explícita («usa Gasolina hoy»). Consejo Las preguntas de ejemplo de cada herramienta están en [Herramientas](/mcp/herramientas/). Si no programas, la página [Asistentes de IA](https://preciosgasolina.es/asistentes-ia/) de la web lo explica paso a paso. # Herramientas del MCP > Las 21 herramientas del servidor MCP de Gasolina hoy por grupos: qué hace cada una, sus argumentos principales y una pregunta de ejemplo. El servidor MCP tiene **21 herramientas de solo lectura** en cuatro grupos. Cada una llama al mismo servicio que su endpoint de la API REST y devuelve `{ data, meta }` en `structuredContent` (con la fecha de los datos, la atribución y `web_url`). Los argumentos marcados con **\*** son obligatorios; el resto, opcionales. Argumentos que se repiten: * **`fuel`**: `gasoline_95`, `gasoline_98`, `diesel`, `diesel_premium`, `lpg` o `cng` (ver [Conceptos básicos](/empezar/conceptos-basicos/)). * **`level`** + **`code`**: territorio. `level` es `spain`, `community`, `province` o `municipality`; `code`, el código INE de la comunidad o provincia (p. ej. `28` para la provincia de Madrid, `13` para la Comunidad de Madrid), el id de municipio o el slug. Usa `search_places` para obtenerlos. * **`limit`**: número de resultados, de 1 a 50 (por defecto 10). * **`lat`**, **`lng`**: coordenadas WGS84 dentro de España (se redondean a 3 decimales). Consejo Las descripciones que lee el modelo están en inglés (es lo que mejor entienden los modelos), pero los datos y los textos de las respuestas están en español. ## Precios y gasolineras [Sección titulada «Precios y gasolineras»](#precios-y-gasolineras) ### `search_places` [Sección titulada «search_places»](#search_places) Busca municipios, códigos postales, provincias, comunidades o gasolineras por nombre y devuelve sus identificadores para el resto de herramientas. Equivale a `GET /v1/search`. * Argumentos: `query`\* (2–100 caracteres: nombre, código postal o gasolinera), `limit` (1–20). * Ejemplo: «¿Qué es 28100? ¿Dónde está la Repsol de la A-6?» ### `find_cheapest_fuel` [Sección titulada «find_cheapest_fuel»](#find_cheapest_fuel) Las gasolineras más baratas de un carburante en España, en un territorio (`level` + `code`) o alrededor de un punto (`lat` + `lng` + `radius_km`). En el ranking de toda España, Canarias, Ceuta y Melilla van aparte salvo `include_low_tax: true`. Equivale a `GET /v1/stations/cheapest`. * Argumentos: `fuel` (por defecto `gasoline_95`), `level`, `code`, `lat`, `lng`, `radius_km` (hasta 50), `limit`, `open_24h`, `brand` (slug: `repsol`, `cepsa`, `bp`, `ballenoil`…), `include_low_tax`. * Ejemplo: «Diésel más barato en Sevilla, a 10 km de mí o abierto 24 horas» ### `find_fuel_near` [Sección titulada «find_fuel_near»](#find_fuel_near) Gasolineras con el carburante a menos de `radius_km` de un punto, por precio o por distancia. Equivale a `GET /v1/stations/nearby`. * Argumentos: `lat`\*, `lng`\*, `radius_km` (hasta 50), `fuel`, `sort` (`price` o `distance`), `limit`, `open_24h`. * Ejemplo: «Gasolineras cerca de la estación de Atocha» ### `get_station` [Sección titulada «get_station»](#get_station) Dirección, horario, coordenadas y precios de hoy de todos los carburantes y productos (AdBlue, HVO, E10…) de una gasolinera. Equivale a `GET /v1/stations/{id}`. * Argumentos: `id`\* (id del Ministerio, p. ej. `14402`, o slug de su ficha). * Ejemplo: «Horario y precios de esta gasolinera» ### `get_fuel_prices` [Sección titulada «get_fuel_prices»](#get_fuel_prices) Media, mediana, mínimo y máximo de hoy de cada carburante en España o en un territorio, con el número de gasolineras, la variación frente al día anterior y la comparación con la media de España. Equivale a `GET /v1/prices`. * Argumentos: `level`, `code`, `fuel`. * Ejemplo: «Precio medio de la gasolina en Valencia hoy frente a España» ### `get_price_history` [Sección titulada «get_price_history»](#get_price_history) Histórico diario (hasta 90 días) de un territorio o de una gasolinera, con la variación del periodo; con `monthly: true`, medias mensuales de España desde 2005 (Boletín Petrolero de la UE, solo `gasoline_95` y `diesel`). Equivale a `GET /v1/history`, `GET /v1/stations/{id}/history` y `GET /v1/history/monthly`. * Argumentos: `fuel` (por defecto `gasoline_95`), `level`, `code`, `station_id`, `days` (1–90), `monthly`, `from` (`AAAA-MM`, solo con `monthly`). * Ejemplo: «¿Cuánto ha subido el diésel este mes?» ### `compare_regions` [Sección titulada «compare_regions»](#compare_regions) Provincias o comunidades ordenadas por el precio medio de hoy de un carburante (la más barata primero), con la diferencia frente a España. Equivale a `GET /v1/rankings/regions`. * Argumentos: `level` (`province` por defecto, o `community`), `fuel` (por defecto `diesel`), `include_low_tax`. * Ejemplo: «¿Qué provincia tiene el diésel más barato?» ### `compare_brands` [Sección titulada «compare_brands»](#compare_brands) Precio medio y tamaño de la red de las marcas en España o en una provincia. Con `brands`, solo esas marcas y sus datos verificados (historia, propietario, carburantes premium) con fuentes. Equivale a `GET /v1/brands` y `GET /v1/brands/{slug}`. * Argumentos: `fuel`, `province` (código INE o slug; por provincia solo hay medias de `gasoline_95` y `diesel`), `brands` (hasta 6 slugs). * Ejemplo: «Repsol, Cepsa y BP en Madrid» ### `get_product_prices` [Sección titulada «get_product_prices»](#get_product_prices) Precio medio y mediana de hoy de un producto y las gasolineras más baratas que lo comunican al Ministerio. Equivale a `GET /v1/products/{id}`. * Argumentos: `product`\* (`adblue`, `diesel_b`, `hvo`, `lng`, `gasoline_95_e10` o `gasoline_98_e10`), `community`, `limit`. * Ejemplo: «¿Dónde hay AdBlue o HVO y a cuánto?» ## Carreteras y rutas [Sección titulada «Carreteras y rutas»](#carreteras-y-rutas) ### `find_routes` [Sección titulada «find_routes»](#find_routes) Busca en el catálogo de rutas en coche y en moto de preciosgasolina.es. Equivale a `GET /v1/routes`. * Argumentos: `query`, `type` (`moto`, `rurales`, `costa`, `montana` o `clasicas`), `region`, `limit`. * Ejemplo: «Rutas en moto por la costa de Andalucía» ### `get_route` [Sección titulada «get_route»](#get_route) Una ruta del catálogo: recorrido, mejor temporada, puntos destacados, fotos con su autor, coste estimado del viaje y las gasolineras más baratas a 3 km o menos del trazado. Equivale a `GET /v1/routes/{slug}`. * Argumentos: `slug`\* (de `find_routes`), `fuel`, `consumption` (L/100 km), `limit`. * Ejemplo: «Ruta de los pueblos blancos: recorrido y dónde repostar» ### `find_fuel_on_road` [Sección titulada «find_fuel_on_road»](#find_fuel_on_road) Gasolineras de una carretera (A-6, AP-7, N-340…) con su punto kilométrico y sentido cuando se conocen, por precio o por posición. Equivale a `GET /v1/roads/{slug}/stations`. * Argumentos: `road`\* (código o slug: `A-3`, `ap-7`), `fuel` (por defecto `gasoline_95`), `sort` (`price` o `position`), `limit`. * Ejemplo: «Gasolineras más baratas en la AP-7» ### `find_fuel_along_route` [Sección titulada «find_fuel_along_route»](#find_fuel_along_route) Las gasolineras más baratas a lo largo de la ruta del usuario, con su posición en el recorrido y el coste estimado del viaje. La ruta se envía como puntos `[lat, lng]` en orden (origen, localidades intermedias, destino): cuantos más puntos, más precisa. Equivale a `POST /v1/route/fuel`. * Argumentos: `points`\* (2–200 pares `[lat, lng]`), `fuel` (por defecto `gasoline_95`), `corridor_km` (hasta 10; por defecto 3), `consumption` (L/100 km), `open_24h`, `limit`. * Ejemplo: «Voy de Madrid a Valencia por la A-3, ¿dónde reposto?» ## Contenido [Sección titulada «Contenido»](#contenido) ### `search_content` [Sección titulada «search_content»](#search_content) Busca en las guías, el blog y las rutas de preciosgasolina.es (tipos de carburante, E10, AdBlue, impuestos, consejos para ahorrar…) y devuelve la respuesta directa de cada pieza y su enlace. Equivale a `GET /v1/content`. * Argumentos: `query`\* (2–100 caracteres), `type` (`guide`, `post` o `route`), `limit`. * Ejemplo: «¿Qué es la gasolina E10?» ### `get_article` [Sección titulada «get_article»](#get_article) Devuelve una guía o un artículo completo, con preguntas frecuentes y fuentes (texto en Markdown). Equivale a `GET /v1/content/{type}/{slug}`. * Argumentos: `type`\* (`guide`, `post` o `route`), `slug`\*. ### `get_monthly_report` [Sección titulada «get_monthly_report»](#get_monthly_report) Informe de un mes cerrado: medias de España frente al mes anterior, días más baratos y más caros y provincias por precio. Sin `month`, lista los meses disponibles. Equivale a `GET /v1/reports` y `GET /v1/reports/{month}`. * Argumentos: `month` (`AAAA-MM`). * Ejemplo: «¿Cómo fueron los precios en septiembre?» ## Calculadoras [Sección titulada «Calculadoras»](#calculadoras) ### `calculate_trip_cost` [Sección titulada «calculate_trip_cost»](#calculate_trip_cost) Coste en combustible de un viaje: kilómetros de ida (o coordenadas de origen y destino: línea recta × 1,25), consumo y precio de hoy (media de España o de una provincia, o el que indiques). Con `tank_capacity`, también el coste de llenar el depósito. Equivale a `GET /v1/calc/trip-cost` y `GET /v1/calc/tank-cost`. * Argumentos: `fuel`, `km`, `from_lat`, `from_lng`, `to_lat`, `to_lng`, `round_trip`, `consumption` (L/100 km; kg con GNC), `price`, `province`, `people` (1–9), `tank_capacity`. * Ejemplo: «¿Cuánto me cuesta ir de Madrid a Valencia con 6,5 L/100 km?» ### `calculate_savings` [Sección titulada «calculate_savings»](#calculate_savings) Ahorro por repostaje, al mes y al año al repostar en una gasolinera más barata, y si compensa el desvío. Equivale a `GET /v1/calc/savings`. * Argumentos: `usual_price`\*, `cheap_price`\*, `fuel`, `quantity_per_refuel`, `refuels_per_month`, `detour_km` (ida y vuelta), `consumption`. * Ejemplo: «¿Compensa desviarme 5 km para ahorrar 8 céntimos?» ### `compare_vehicle_costs` [Sección titulada «compare_vehicle_costs»](#compare_vehicle_costs) Coste por 100 km y al año, amortización y kilómetros a partir de los que compensa un diésel frente a un gasolina (`compare: "petrol_vs_diesel"`) o un eléctrico frente a uno de combustión (`compare: "ev_vs_fuel"`), con los precios de hoy. Equivale a `GET /v1/calc/vehicle-costs`. * Argumentos: `compare`\*, `km_per_year`\*, `petrol_consumption`, `diesel_consumption`, `diesel_extra_price`, `diesel_extra_yearly_cost`, `ev_consumption` (kWh/100 km), `electricity_price` (€/kWh), `ev_extra_price`. * Ejemplo: «¿Me compensa un diésel o un eléctrico con 20.000 km al año?» ### `calculate_adblue` [Sección titulada «calculate_adblue»](#calculate_adblue) Litros y euros de AdBlue al mes y al año de un diésel, con el precio medio de hoy en surtidor (o el que indiques). Equivale a `GET /v1/calc/adblue`. * Argumentos: `km_per_year`\*, `litres_per_1000km`, `price`, `tank_litres`. * Ejemplo: «¿Cuánto AdBlue gasto al mes?» ### `explain_fuel_price` [Sección titulada «explain_fuel_price»](#explain_fuel_price) Cuánto de un litro es IVA, Impuesto sobre Hidrocarburos (con la rebaja vigente) y producto, logística y margen; régimen de Canarias, Ceuta y Melilla. Sin precio, usa la media de hoy. Incluye los tramos de la rebaja y las fuentes. Equivale a `GET /v1/calc/price-breakdown` + `GET /v1/taxes`. * Argumentos: `fuel` (`gasoline_95`, `gasoline_98`, `diesel` o `diesel_premium`), `price`, `province`, `tank_litres`. * Ejemplo: «¿Cuánto de un litro son impuestos con la rebaja?» ## Errores de las herramientas [Sección titulada «Errores de las herramientas»](#errores-de-las-herramientas) Si una herramienta no puede responder, el resultado lleva `isError: true` y un texto con el código y el motivo, por ejemplo `PROVINCE_NOT_FOUND: No existe la provincia 99.` o `INVALID_PARAMETER: …`. Los códigos son los mismos que los de la API REST: ver [Errores](/conceptos/errores/). Un argumento que no cumple el esquema de entrada (tipo o rango) se rechaza antes de ejecutar la herramienta. # Recursos y prompts del MCP > Recursos del servidor MCP de Gasolina hoy (carburantes, territorios, metodología, guías, blog y rutas en Markdown) y sus cuatro prompts con argumentos. Además de las [herramientas](/mcp/herramientas/), el servidor MCP ofrece **recursos** (datos de referencia que el cliente puede leer y adjuntar a la conversación) y **prompts** (plantillas de conversación que el usuario elige en su cliente). ## Recursos [Sección titulada «Recursos»](#recursos) | URI | Contenido | Tipo | | -------------------- | -------------------------------------------------------------------------------------------------------------------- | ------------------ | | `fuel://fuel-types` | Identificadores, nombres y unidades de los carburantes, y los identificadores de los productos. | `application/json` | | `fuel://territories` | Comunidades autónomas y provincias con su código INE, slug y nombre (las provincias, con el código de su comunidad). | `application/json` | | `fuel://methodology` | Metodología: fuente, frecuencia, cobertura, limitaciones y licencia. | `text/markdown` | ### Plantillas de recursos [Sección titulada «Plantillas de recursos»](#plantillas-de-recursos) Leen el contenido de preciosgasolina.es en Markdown (título, respuesta directa, texto completo, preguntas frecuentes y enlace a la fuente). `{slug}` es el de la pieza en la web (búscalo con la herramienta `search_content` o con `GET /v1/content`). | Plantilla | Contenido | | -------------------------------- | ------------------------------- | | `preciosgasolina://guias/{slug}` | Una guía de preciosgasolina.es. | | `preciosgasolina://blog/{slug}` | Un artículo del blog. | | `preciosgasolina://rutas/{slug}` | Una ruta por carretera. | Ejemplo de lectura con JSON-RPC: ```json { "jsonrpc": "2.0", "id": 3, "method": "resources/read", "params": { "uri": "fuel://methodology" } } ``` ## Prompts [Sección titulada «Prompts»](#prompts) Los prompts aparecen en el menú de tu cliente (por ejemplo, con «/» o con el botón de adjuntar) y generan una petición que ya dice qué herramientas usar y que hay que citar la fecha y la fuente. | Prompt | Para qué | Argumentos | | ----------------------- | -------------------------------------------------------------------------------------------- | ----------------------------------------------------------- | | `planificar_viaje` | Coste del combustible, paradas baratas en el recorrido y una ruta del catálogo si encaja. | `origen`\*, `destino`\*, `consumo` (L/100 km), `carburante` | | `repostar_barato_cerca` | Las gasolineras más baratas cerca de un lugar, con precio, dirección, si abre 24 h y enlace. | `lugar`\*, `carburante` | | `entender_el_precio` | Impuestos y rebaja de un litro y evolución del precio en 30 días y desde 2022. | `carburante` | | `comparar_marcas` | Precio medio, red y datos de varias marcas en una zona, sin opiniones. | `marcas`\*, `zona` | \* Obligatorio. Los argumentos son texto libre (por ejemplo, `carburante: "diésel"`); en `repostar_barato_cerca` y `entender_el_precio`, si no se indica el carburante, se usa la gasolina 95. Ejemplo: ```json { "jsonrpc": "2.0", "id": 4, "method": "prompts/get", "params": { "name": "planificar_viaje", "arguments": { "origen": "Madrid", "destino": "Valencia", "consumo": "6,5" } } } ``` # Registro de cambios > Cambios de la API REST, del servidor MCP y de la documentación de Gasolina hoy, con fecha. Lanzamiento de la v1 el 7 de octubre de 2026. Los cambios de la API REST, del servidor MCP y de sus límites, del más reciente al más antiguo. Ver también [Versionado](/conceptos/versionado/). ## 7 de octubre de 2026 · Lanzamiento de la v1 Nuevo [Sección titulada «7 de octubre de 2026 · Lanzamiento de la v1 »](#7-de-octubre-de-2026--lanzamiento-de-la-v1-) * **API REST v1** en `https://api.preciosgasolina.es/v1`: 30 endpoints de solo lectura (precios, gasolineras, histórico, territorios, marcas, productos, carreteras y rutas, contenido, calculadoras y estado), sobre `{ data, meta }`, errores RFC 9457 y especificación [OpenAPI 3.1](https://api.preciosgasolina.es/v1/openapi.json). * **Servidor MCP** en `https://mcp.preciosgasolina.es/mcp`: 21 herramientas, 3 recursos, 3 plantillas de recursos y 4 prompts; Streamable HTTP sin estado y sin inicio de sesión. * **Límites iniciales** por IP: 120 peticiones por minuto (20 cada 10 segundos) en la API REST, 30 por minuto en las consultas pesadas, y 60 mensajes y 30 llamadas a herramientas por minuto en el MCP. * **Documentación** en `docs.preciosgasolina.es`, con versión Markdown de cada página, `llms.txt` y `llms-full.txt`. * Gratis y con licencia CC BY 4.0 con atribución. # Términos de uso > Condiciones de uso de la API y del MCP de Gasolina hoy: servicio gratuito, licencia CC BY 4.0 con atribución, sin garantía de tiempo real, uso razonable. Estas condiciones se aplican a la API REST (`api.preciosgasolina.es`) y al servidor MCP (`mcp.preciosgasolina.es`) de Gasolina hoy. Al usarlos, las aceptas. Completan el [aviso legal](https://preciosgasolina.es/aviso-legal/) y la [política de privacidad](https://preciosgasolina.es/privacidad/) de preciosgasolina.es. ## Quién presta el servicio [Sección titulada «Quién presta el servicio»](#quién-presta-el-servicio) Gasolina hoy (preciosgasolina.es) es un servicio de ONETOUCH SA de CV, con domicilio en San Pedro Sula (Cortés, Honduras). Los datos de contacto completos están en el [aviso legal](https://preciosgasolina.es/aviso-legal/). ## 1. Servicio gratuito [Sección titulada «1. Servicio gratuito»](#1-servicio-gratuito) La API y el servidor MCP son gratuitos y no requieren registro ni clave. Gasolina hoy puede cambiar, limitar o interrumpir el servicio, total o parcialmente, en cualquier momento, aunque procurará anunciar los cambios importantes en el [registro de cambios](/changelog/). ## 2. Licencia y atribución [Sección titulada «2. Licencia y atribución»](#2-licencia-y-atribución) Los datos se ofrecen con la licencia [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/deed.es). Puedes usarlos, también con fines comerciales, siempre que muestres la atribución de `meta.attribution` y, cuando sea posible, enlaces `meta.web_url`. Detalles en [Atribución y licencia](/empezar/atribucion-y-licencia/). La licencia no da derechos sobre la marca ni el logotipo de Gasolina hoy, ni sobre las marcas de las gasolineras. ## 3. Sin garantía de exactitud ni de tiempo real [Sección titulada «3. Sin garantía de exactitud ni de tiempo real»](#3-sin-garantía-de-exactitud-ni-de-tiempo-real) Los precios son los que las gasolineras comunican al Ministerio para la Transición Ecológica y el Reto Demográfico y se actualizan dos veces al día. **No son precios en tiempo real** y pueden no coincidir con el del surtidor. El servicio se presta «tal cual», sin garantía de exactitud, disponibilidad ni adecuación a un fin concreto. No lo uses como única base para decisiones en las que un error de precio o una interrupción pueda causar un daño. ## 4. Uso razonable y límites [Sección titulada «4. Uso razonable y límites»](#4-uso-razonable-y-límites) * Respeta los [límites de uso](/conceptos/limites/) y la cabecera `Retry-After`. * Cachea las respuestas hasta `meta.next_update`. * No intentes eludir los límites (por ejemplo, repartiendo peticiones entre muchas IP) ni uses la API para descargar todos los datos: para eso están los [datos abiertos](https://preciosgasolina.es/datos/). * No uses el servicio para actividades ilícitas ni para dañar su funcionamiento o el de preciosgasolina.es. Gasolina hoy puede bloquear el acceso a quien incumpla estas condiciones. ## 5. Responsabilidad [Sección titulada «5. Responsabilidad»](#5-responsabilidad) En la medida que permita la ley, Gasolina hoy no responde de los daños derivados del uso de los datos, de errores en ellos o de interrupciones del servicio. ## 6. Cambios en estas condiciones [Sección titulada «6. Cambios en estas condiciones»](#6-cambios-en-estas-condiciones) Estas condiciones pueden cambiar. La fecha de la última revisión aparece al final de esta página.