# Spain BOE Official Gazette Feed (oposiciones, licitaciones) (`lafabbricallc/spain-boe-daily-gazette`) Actor

Every item published in Spain's Official State Gazette (BOE) per day as flat rows from the official open-data API: section, department, title, id, PDF/HTML/XML links. Filter by section (job competitions, tenders, laws), keyword, department and date range. No personal data.

- **URL**: https://apify.com/lafabbricallc/spain-boe-daily-gazette.md
- **Developed by:** [La Fabbrica LLC](https://apify.com/lafabbricallc) (community)
- **Categories:** Lead generation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 gazette items

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### What does Spain BOE Official Gazette Feed do?

Spain BOE Official Gazette Feed turns the **Boletín Oficial del Estado**, Spain's official state gazette, into flat, spreadsheet-ready rows: one row per published item with its section, issuing department, epigraph, full title, official identifier and direct PDF, HTML and XML links. It reads the gazette's own open-data JSON API (`boe.es/datosabiertos`), so there is no HTML parsing to break and each day is a single request.

Pick a date range (default: the last four days), the sections you care about and optional keyword or department filters, and you get for example:

- every new **public-sector job competition** (section II.B, *oposiciones y concursos*) convened this week,
- every **public tender, award or contract formalisation** (section V.A, *contratación del sector público*) from a given ministry,
- every **law, royal decree or ministerial order** published in section I,
- **grants, agreements and other resolutions** from section III, and other official notices from V.B and V.C.

An optional `BORME` mode returns the section-level entries of the Boletín Oficial del Registro Mercantil (one row per province PDF per day) so you can monitor which issues exist and link to them; it never parses the company acts inside those PDFs.

The actor runs with Apify's **limited permissions** level: it can only read and write its own run storages and never touches other data in your account. It does **not** log in and does **not** collect personal data: the two gazette sections whose items are about named individuals (II.A appointments and IV court notices) are never returned, and any individual's name that follows an honorific in a remaining title is replaced by `[nombre omitido]`.

### Why use it?

- **Opositores academies, job-alert sites and HR consultancies**: a daily JSON/CSV feed of every new *convocatoria* with the corps or body in `epigraph` and the ministry or university in `department`, ready for e-mail alerts.
- **Bid teams and sales ops**: all section V.A notices filtered by keyword (`"suministro"`, `"servicios de limpieza"`, `"software"`) or department, with the PDF link to the full notice.
- **Legal-tech and compliance pipelines**: monitor section I for new legislation by keyword (`"protección de datos"`, `"IVA"`) and store the XML link for downstream parsing.
- **AI agents and RAG**: "What did the BOE publish about renewable energy this week?" becomes one actor call with `keywords` and `daysBack`.

On Apify you also get scheduling, webhooks, run monitoring and integrations (Google Sheets, Make, Zapier, LangChain, MCP).

### How to use it

On the actor page, open the **Input** tab, set a date range and the sections you want, optionally add keywords, and click **Start**. Leave every field at its default to get the newest 100 items across all supported sections from the last four days. The fields:

| Field | Type | Default | Meaning |
|---|---|---|---|
| `publication` | `BOE` / `BORME` | `BOE` | Which gazette to read |
| `daysBack` | integer 1-62 | `4` | Look back this many days from `dateTo` (or today) when `dateFrom` is empty; days without an issue are skipped |
| `dateFrom`, `dateTo` | `YYYY-MM-DD` | none / today | Explicit range, at most 62 days per run; the API covers 1960 onwards |
| `sections` | array | all supported | `1`, `2B`, `3`, `5A`, `5B`, `5C`, `T`, or names such as `"oposiciones"`, `"licitaciones"`, `"II.B"`, `"V.A"`; for BORME `A`, `B`, `C` |
| `keywords` | array | none | Keep items whose title, epigraph or department contains any of these (accent- and case-insensitive) |
| `excludeKeywords` | array | none | Drop items containing any of these |
| `departments` | array | none | Keep items whose issuing body contains any of these |
| `maxItems` | integer | `100` | Stop after this many rows, newest issue first (max 20,000) |

Sections II.A (*nombramientos*) and IV (*Administración de Justicia*) are not available; asking for them returns an error explaining why.

#### Example input

New job competitions from the last week, only convocations:

```json
{
    "sections": ["2B"],
    "keywords": ["convoca", "pruebas selectivas", "concurso"],
    "daysBack": 7,
    "maxItems": 200
}
```

Public tenders published between two dates, without contract formalisations:

```json
{
    "sections": ["licitaciones"],
    "dateFrom": "2026-09-21",
    "dateTo": "2026-09-25",
    "excludeKeywords": ["formalización"],
    "maxItems": 500
}
```

Everything the Ministry of Finance published today and yesterday:

```json
{
    "departments": ["Ministerio de Hacienda"],
    "daysBack": 2,
    "maxItems": 100
}
```

### What data does it return?

One row per gazette item. Rows come newest issue first, in the gazette's own order inside each issue.

| Field | Meaning |
|---|---|
| `publication` | `BOE` or `BORME` |
| `date`, `gazetteNumber` | Publication date (`YYYY-MM-DD`) and issue number |
| `section`, `sectionTitle`, `sectionEnglish` | Section code (`1`, `2B`, `3`, `5A`, `5B`, `5C`, `T`), its Spanish heading and an English gloss |
| `department` | Issuing body: ministry, court, autonomous community, university, public company |
| `epigraph` | Sub-heading under the department (for II.B usually the corps or scale; for I the subject) |
| `id` | Official identifier (`BOE-A-2026-19865`, `BOE-B-2026-30881`), stable and unique |
| `controlNumber` | The gazette's internal control number, when present |
| `title` | Full title as published; a person's name after an honorific becomes `[nombre omitido]` |
| `personalDataRedacted` | `true` when a name was masked in `title` |
| `isTender`, `isJobCompetition` | Convenience flags for section V.A and II.B rows |
| `pdfUrl`, `pdfBytes`, `pageStart`, `pageEnd` | The item's PDF, its size and its pages in the printed issue |
| `htmlUrl`, `xmlUrl` | The item's HTML text and XML on boe.es |
| `summaryPdfUrl` | The whole issue's summary PDF |
| `sourceAttribution` | Attribution line required by the BOE reuse terms |
| `retrievedAt` | UTC time the actor downloaded the issue |

#### Example output

```json
{
    "publication": "BOE",
    "date": "2026-09-25",
    "gazetteNumber": "237",
    "section": "5A",
    "sectionTitle": "V. Anuncios. - A. Contratación del Sector Público",
    "sectionEnglish": "V.A. Public-sector procurement notices (tenders, awards)",
    "department": "MINISTERIO DE LA PRESIDENCIA, JUSTICIA Y RELACIONES CON LAS CORTES",
    "epigraph": null,
    "id": "BOE-B-2026-30881",
    "controlNumber": null,
    "title": "Anuncio de licitación de: Consejo de Administración del Patrimonio Nacional. Objeto: Contrato de servicios de producción audiovisual y multimedia, para la grabación, postproducción y edición de contenidos corporativos de Patrimonio Nacional. Expediente: 202610PA0319.",
    "personalDataRedacted": false,
    "isTender": true,
    "isJobCompetition": false,
    "pdfUrl": "https://www.boe.es/boe/dias/2026/09/25/pdfs/BOE-B-2026-30881.pdf",
    "pdfBytes": 208263,
    "pageStart": 50195,
    "pageEnd": 50195,
    "htmlUrl": "https://www.boe.es/diario_boe/txt.php?id=BOE-B-2026-30881",
    "xmlUrl": "https://www.boe.es/diario_boe/xml.php?id=BOE-B-2026-30881",
    "summaryPdfUrl": "https://www.boe.es/boe/dias/2026/09/25/pdfs/BOE-S-2026-237.pdf",
    "sourceAttribution": "Fuente de los datos: Agencia Estatal Boletín Oficial del Estado",
    "retrievedAt": "2026-09-26T03:14:37.080Z"
}
```

### How much does it cost?

The actor is priced **pay-per-event**: a flat **$0.02 per run** plus **$0.003 per gazette item** saved to the dataset. You pay only for rows you receive; filtered-out items and failed runs cost nothing beyond the start fee.

| Run | Rows | Price |
|---|---|---|
| One ministry's items, two days | 15 | $0.07 |
| Default (newest 100 items) | 100 | $0.32 |
| A week of job competitions | ~150 | $0.47 |
| A full week of every supported section | ~900 | $2.72 |

Platform usage (compute) is well under one cent per run and is included in your Apify plan. Set **Maximum cost per run** in the run options to cap what a run may charge; the actor stops cleanly at the cap.

### Limits and things to know

- The BOE appears Monday to Saturday; there is no issue on Sundays or national holidays, and the day's issue goes online around 07:30 Madrid time. Days without an issue are skipped and counted in the run's `SUMMARY` record.
- One run covers at most 62 days. For a longer history, schedule several runs or split the range.
- Filters match on `title`, `epigraph` and `department` only; the actor does not download or read the item PDFs.
- The summary API lists what was published; it does not carry deadlines, budgets or CPV codes. Follow `pdfUrl` / `xmlUrl` for the full text.
- BORME mode returns one row per section entry (usually a province), not the individual company acts, which name company directors.
- Memory: the default 512 MB is enough for any range; a 62-day run with all sections is about 10,000 rows.

### Data licence and attribution

The data comes from the Agencia Estatal Boletín Oficial del Estado open-data API (`www.boe.es/datosabiertos`). Reuse, including commercial reuse, is permitted under the agency's legal notice and Spain's public-sector information law (Ley 37/2007) provided the source is credited. Every row carries the required line in `sourceAttribution`: "Fuente de los datos: Agencia Estatal Boletín Oficial del Estado". Keep it when you republish the data.

### Personal data

None is collected. Sections II.A (appointments, transfers, retirements of named officials) and IV (court notices) are excluded at source. In the remaining sections a small number of titles mention a person after an honorific (for example a decoration awarded to a named official); that name is replaced by `[nombre omitido]` and the row is flagged `personalDataRedacted: true`. No contact, e-mail or phone fields exist in the source.

### FAQ and support

**Why did my run return nothing?** Most likely the range only covered a Sunday or a holiday, or today's issue is not online yet. Raise `daysBack` or set `dateFrom`.

**Can I get the full text of an item?** Not from this actor; use the `htmlUrl` or `xmlUrl` of each row, which point to the official text.

**Can I get section II.A or IV?** No. Those sections consist of items about named individuals and are excluded by design.

**Does it cover regional gazettes (BOJA, DOGC, BOCM)?** No, only the state BOE and the BORME summary. Open an issue on the actor page if you need another source.

# Actor input Schema

## `publication` (type: `string`):

"BOE" (Boletín Oficial del Estado, default) returns every item of the daily gazette. "BORME" (Boletín Oficial del Registro Mercantil) returns the section-level entries of the commercial-register gazette (one row per province PDF), never the company acts inside them.

## `daysBack` (type: `integer`):

How many days to look back from "Date to" (or today) when "Date from" is empty. Days without a gazette (Sundays, holidays) are skipped. 1-62.

## `dateFrom` (type: `string`):

First publication day, YYYY-MM-DD (e.g. "2026-09-22"). Overrides "Days back". The API covers 1960 onwards; one run may span at most 62 days.

## `dateTo` (type: `string`):

Last publication day, YYYY-MM-DD. Defaults to today (UTC). Today's BOE goes online around 07:30 Madrid time.

## `sections` (type: `array`):

BOE sections to include, by code or name: "1" (I. Disposiciones generales), "2B" (II.B Oposiciones y concursos), "3" (III. Otras disposiciones), "5A" (V.A Contratación del Sector Público: licitaciones, adjudicaciones), "5B" (V.B Otros anuncios oficiales), "5C" (V.C Anuncios particulares), "T" (Tribunal Constitucional). Also accepts "oposiciones", "licitaciones", "II.B", "V.A". Leave empty for all of them. Sections II.A (appointments) and IV (court notices) are never returned because their items name individual people. For BORME use "A", "B" or "C".

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

Keep only items whose title, epigraph or department contains at least one of these words or phrases. Case- and accent-insensitive substring match, e.g. "convoca", "licitación", "subvenciones", "Cuerpo Superior".

## `excludeKeywords` (type: `array`):

Drop items whose title, epigraph or department contains any of these, e.g. "corrección de errores".

## `departments` (type: `array`):

Keep only items whose issuing body (departamento) contains one of these, e.g. "Ministerio de Hacienda", "Universidades", "Comunidad Autónoma de Andalucía". Accent-insensitive substring match.

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

Stop after this many rows (newest gazette first). Each row is one pay-per-event result. A full BOE day has roughly 100-250 items in the supported sections.

## Actor input object example

```json
{
  "publication": "BOE",
  "daysBack": 4,
  "dateFrom": "2026-09-22",
  "dateTo": "2026-09-25",
  "sections": [
    "2B",
    "5A"
  ],
  "keywords": [
    "convoca",
    "pruebas selectivas"
  ],
  "excludeKeywords": [
    "corrección de errores"
  ],
  "departments": [
    "Ministerio de Hacienda"
  ],
  "maxItems": 100
}
```

# Actor output Schema

## `items` (type: `string`):

No description

## `itemsCsv` (type: `string`):

No description

# 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 = {
    "daysBack": 4,
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("lafabbricallc/spain-boe-daily-gazette").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 = {
    "daysBack": 4,
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("lafabbricallc/spain-boe-daily-gazette").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 '{
  "daysBack": 4,
  "maxItems": 100
}' |
apify call lafabbricallc/spain-boe-daily-gazette --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lafabbricallc/spain-boe-daily-gazette"
        }
    }
}
```

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/o6donp3HntNvB9LG4/builds/e2KMdrOMcotY4npH5/openapi.json
