# Basque Country Public Tenders Index Scraper (`xamto1987/euskadi-tenders`) Actor

Indice de anuncios de contratacion publica del Pais Vasco (Open Data Euskadi / Kontratazio Publikoen Plataforma): anuncios en plazo o volcado anual completo. Basque Country public procurement announcements index.

- **URL**: https://apify.com/xamto1987/euskadi-tenders.md
- **Developed by:** [Santi Belloso Lopez](https://apify.com/xamto1987) (community)
- **Categories:** Lead generation, Automation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Basque Country Public Tenders Index Scraper · Anuncios de contratación del País Vasco

Extrae el **índice de anuncios de contratación pública del País Vasco**
(Gobierno Vasco, diputaciones forales, ayuntamientos y demás entidades
adheridas a la Kontratazio Publikoen Plataforma) desde el catálogo oficial
**Open Data Euskadi**.

Scrapes the **Basque Country's public procurement announcements index**
(regional government, provincial councils, town halls and other affiliated
bodies) from the official **Open Data Euskadi** catalogue.

***

### 🇪🇸 Español

#### Qué obtienes

Un ítem por anuncio de contratación:

| Campo | Qué es |
|---|---|
| `idExpediente` | Número de expediente del órgano |
| `titulo`, `objeto` | Título y objeto del anuncio |
| `administracion` | Entidad (institución) |
| `organoContratacion` | Poder adjudicador |
| `organoSuperior` | Departamento |
| `unidadTramitadora` | Órgano de contratación concreto |
| `estado` | Estado de tramitación (`Abierto / Plazo de presentación`, `Adjudicación provisional / definitiva`…) |
| `esContratoMenor` | Booleano |
| `fechaPublicacionAnuncio`, `fechaLimiteOfertas` | Fechas, en ISO |
| `enlaceFichaPublica` | Ficha pública oficial del expediente |

#### ⚠️ Limitación importante, verificada y documentada: sin importes ni adjudicatario

A diferencia de `catalonia-tenders` y `aragon-tenders`, este actor **NO**
incluye presupuesto, importe de adjudicación ni datos del adjudicatario.
No es una carencia de implementación: es una limitación **real y
verificada** del origen de datos.

- El índice público (el que usa este actor) no lleva esos campos —
  verificado con curl sobre el volcado JSON completo.
- El detalle de cada expediente (que sí los lleva) solo está disponible en
  dos rutas técnicas, **ambas prohibidas por el `robots.txt`** de
  `contratacion.euskadi.eus`: `Disallow: /*/es_*/data/*` (el JSON/XML de
  detalle) y `Disallow: /*idxContent*` (los metadatos indexados).
- La página HTML pública del expediente sí está permitida por robots, pero
  es una aplicación de página única que pinta el detalle en el navegador
  leyendo precisamente el recurso prohibido — verificado que el HTML crudo
  no contiene el adjudicatario.
- Existe un tercer recurso (`trazabilidad`) que sí está permitido por
  robots y sí contiene el adjudicatario, pero el identificador interno que
  necesita esa URL solo aparece dentro del propio recurso prohibido —
  callejón sin salida conforme con robots.txt.

Este actor **nunca** solicita las rutas prohibidas. El resultado es un
índice de oportunidades de licitación (quién, qué, cuándo, en qué estado y
enlace a la ficha oficial), no un registro económico completo. Ver la
evidencia curl completa en `docs/fase5/socrata-ccaa.md`.

#### El filtrado ocurre en CLIENTE, no en servidor

A diferencia de Cataluña (Socrata) y Aragón (CKAN), esta plataforma **no
ofrece ningún parámetro de consulta** (`?q=`, `?filters=`…) — verificado con
curl. El actor descarga el volcado JSON completo del periodo elegido
(`fuente`) y aplica `keywords`/`fechaDesde`/`fechaHasta`/`soloContratoMenor`
en memoria, documentado en cada log de ejecución.

#### Parámetros de entrada

| Parámetro | Tipo | Por defecto | Descripción |
|---|---|---|---|
| `fuente` | `abiertos`|`anio` | `abiertos` | `abiertos` = solo anuncios actualmente en plazo (rápido, ~500 filas). `anio` = volcado histórico completo de un año |
| `anio` | entero | `2025` | Solo si `fuente: anio`. Disponible desde 2005 |
| `keywords` | lista de textos | `[]` | Busca en título+objeto, EN CLIENTE |
| `soloContratoMenor` | booleano | `false` | Filtro en cliente |
| `fechaDesde` / `fechaHasta` | fecha ISO | — | Filtro en cliente sobre la fecha de publicación |
| `maxItems` | entero | `200` | Tope de ítems |

#### Fuente y aviso legal

- **Fuente oficial**: Open Data Euskadi, catálogo del Gobierno Vasco —
  `https://opendata.euskadi.eus/contenidos/ds_contrataciones/`. Volcado
  "anuncios en plazo abierto" verificado el 23-ago-2026 (501 filas, ~1,3
  MB, actualización diaria); volcado anual 2025 verificado el mismo día
  (96.829 filas, ~229 MB).
- Este actor respeta estrictamente el `robots.txt` de
  `contratacion.euskadi.eus` (no solicita `dataXML` ni `metadataXML`).
- Este actor **solo lee datos públicos**, sin login, sin cookies y sin
  saltarse ninguna medida técnica. No es un producto oficial ni está
  afiliado, respaldado ni verificado por el Gobierno Vasco.

***

### 🇬🇧 English

#### What it does

`euskadi-tenders` scrapes the **Basque Country's public procurement
announcements index** from the official Open Data Euskadi catalogue.

#### Important, verified limitation: no amounts or awardee data

Unlike `catalonia-tenders`/`aragon-tenders`, this actor does **not**
include budget, award amount or awardee identity. This is a real, verified
platform limitation, not a shortcut: the only two endpoints that carry that
detail are explicitly blocked by `contratacion.euskadi.eus`'s `robots.txt`
(`Disallow: /*/es_*/data/*` and `Disallow: /*idxContent*`), and the public
HTML detail page (which robots.txt does allow) renders that data client-side
from precisely those blocked endpoints — verified empty in the raw HTML.
This actor never requests the disallowed paths. See
`docs/fase5/socrata-ccaa.md` for full curl evidence.

#### Client-side filtering

This platform exposes no query parameters at all (verified with curl) — the
actor downloads the full JSON dump for the chosen period and filters in
memory.

#### Disclaimer

Data comes from Open Data Euskadi, the Basque Government's official open
data catalogue. This actor is **not** an official product and is not
affiliated with or endorsed by the Gobierno Vasco / Eusko Jaurlaritza.

***

**Palabras clave / Keywords**: licitaciones País Vasco, contratación
pública Euskadi, Kontratazio Publikoen Plataforma, Gobierno Vasco, Eusko
Jaurlaritza, anuncios de licitación, open data Euskadi, public procurement
Basque Country.

# Actor input Schema

## `fuente` (type: `string`):

`abiertos` (por defecto) = solo los anuncios ACTUALMENTE en plazo de presentación de ofertas (volcado pequeño, se actualiza a diario, ejecución rápida). `anio` = volcado histórico completo de un año concreto (`anio`), mucho más grande (decenas de miles de filas) e incluye anuncios ya cerrados/adjudicados. / `abiertos` = currently open tenders only (small, daily, fast). `anio` = full historical yearly dump (much larger).

## `anio` (type: `integer`):

Año del volcado histórico a descargar. Disponible desde 2005. Se ignora si `fuente` es `abiertos`. ⚠️ Los volcados anuales recientes tienen decenas de miles de filas (el de 2025 pesa ~230 MB): la ejecución puede tardar varios minutos solo en descargar el fichero. / Year of the historical dump; ignored when `fuente` is `abiertos`. Recent years are large (tens of thousands of rows).

## `keywords` (type: `array`):

Lista de términos a buscar en el título y objeto del contrato. ⚠️ Filtro EN CLIENTE: esta fuente no ofrece parámetros de búsqueda en servidor (verificado con curl, no expone `?q=`). Vacío = sin filtro. / Client-side filter — this source has no server-side query API (verified with curl).

## `soloContratoMenor` (type: `boolean`):

Filtra (en cliente) solo anuncios marcados como contrato menor por la propia fuente. / Client-side filter for minor (direct-award) contracts only.

## `fechaDesde` (type: `string`):

Solo anuncios publicados a partir de esta fecha (filtro EN CLIENTE, formato ISO AAAA-MM-DD). / Client-side date filter, ISO format.

## `fechaHasta` (type: `string`):

Solo anuncios publicados hasta esta fecha (filtro EN CLIENTE, formato ISO AAAA-MM-DD). / Client-side date filter, ISO format.

## `maxItems` (type: `integer`):

Número máximo de anuncios a guardar en el dataset. El actor para limpiamente al alcanzarlo. / Hard cap on dataset items.

## Actor input object example

```json
{
  "fuente": "abiertos",
  "anio": 2025,
  "keywords": [],
  "soloContratoMenor": false,
  "maxItems": 50
}
```

# Actor output Schema

## `results` (type: `string`):

Anuncios de contratación pública del País Vasco normalizados. JSON, CSV o Excel.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("xamto1987/euskadi-tenders").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "maxItems": 50 }

# Run the Actor and wait for it to finish
run = client.actor("xamto1987/euskadi-tenders").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "maxItems": 50
}' |
apify call xamto1987/euskadi-tenders --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,xamto1987/euskadi-tenders"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/kad04Y3qCM46C5Q7P/builds/9qWBc3bmdskkjQDGJ/openapi.json
