# Borme Spain Corporate Acts Gazette Scraper (`jungle_synthesizer/borme-spain-corporate-acts-gazette-scraper`) Actor

Daily Spanish corporate-acts gazette (BORME) parsed into structured incorporations, officer changes, capital moves and dissolutions across all 52 mercantile registries.

- **URL**: https://apify.com/jungle\_synthesizer/borme-spain-corporate-acts-gazette-scraper.md
- **Developed by:** [BowTiedRaccoon](https://apify.com/jungle_synthesizer) (community)
- **Categories:** Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.80 / 1,000 record scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Borme Spain Corporate Acts Gazette Scraper

Pull Spain's daily corporate-acts gazette (BORME — Boletín Oficial del Registro Mercantil) as
structured data instead of dense legal paragraphs. Every incorporation, director appointment or
removal, capital change, address change, merger and dissolution published in Spain is parsed into
typed fields — officer names with their roles, capital amounts as numbers, corporate purpose as
its own field — with the raw published text always included alongside.

***

### Borme Spain Corporate Acts Gazette Scraper Features

- Structured act parsing, not a raw paragraph dump — officer appointments/removals, capital
  amounts, registered addresses and corporate purpose are each their own field
- Covers all three BORME sections in one run: A (company registrations), B (other registry acts)
  and C (legal notices), across every one of Spain's 52 mercantile-registry provinces
- Every act keeps its raw published text (`act_text`) alongside the parsed fields, so nothing is
  lost when a clause form isn't one of the common types
- Date-range driven — pull the last few days for a lead feed, or dial in any historical range back
  to 2009 for a backfill
- Resumable — a capped or interrupted run picks up exactly where it left off, at no extra charge
  for records already delivered

***

### Who Uses Spanish Corporate-Acts Data?

- **B2B lead generation** — newly incorporated companies (`act_type_code: "constitucion"`) with
  registered address, corporate purpose and founding administrator in one row
- **KYB / compliance monitoring** — track officer appointments and removals on companies you
  already track, or watch a whole province for change
- **M\&A and legal research** — capital increases/reductions, mergers and dissolutions as they're
  published, with the source PDF/HTML linked from every row
- **Data vendors and analysts** — a clean, typed feed of Spain's official company-formation
  registry instead of building your own text parser

***

### How Borme Spain Corporate Acts Gazette Scraper Works

1. You give it a date range (or take the default: the last 7 days).
2. For each date, it reads that day's published gazette — every section, every province, in one
   pass.
3. Each entry's published text is parsed into typed fields: officers appointed/removed with role,
   capital amount as a number, corporate purpose, registered address, incorporation date, and more
   — matched against BORME's own act-type vocabulary (Constitución, Nombramientos,
   Ceses/Dimisiones, Ampliación/Reducción de capital, Disolución, Extinción, Cambio de domicilio,
   Fusión, and others).
4. The raw published text is always kept on the row too, so a clause form the parser doesn't
   recognize is never silently dropped.

***

### Input

```json
{
  "startDate": "2025-08-18",
  "endDate": "2025-08-22",
  "maxItems": 100
}
```

| Field       | Type    | Default             | Description |
|-------------|---------|---------------------|-------------------------------------------------------------------------------------------------|
| `startDate` | string  | 7 days before today | First publication date to fetch, inclusive (`YYYY-MM-DD`). BORME has published since 2009. |
| `endDate`   | string  | today               | Last publication date to fetch, inclusive (`YYYY-MM-DD`). |
| `maxItems`  | integer | 15                  | Maximum number of corporate-act records to save. Set higher for a wider pull; there is no cap on how far back `startDate` can go. |

Weekends and Spanish public holidays have no gazette issue — those dates are skipped, not treated
as an error.

#### Pulling a full historical backfill

```json
{
  "startDate": "2009-01-01",
  "endDate": "2026-09-26",
  "maxItems": 0
}
```

`maxItems: 0` pulls everything in the date range. A full backfill is a large, long-running pull —
see **Resuming a large crawl** below if it's capped or interrupted partway through.

***

### Borme Spain Corporate Acts Gazette Scraper Output Fields

```json
{
  "act_id": "BORME-A-2025-157-02-375259",
  "publication_date": "2025-08-20",
  "borme_issue": "157",
  "section": "A",
  "province": "Albacete",
  "registry": "Registro Mercantil de Albacete",
  "company_name": "CASA LOOP SOCIEDAD LIMITADA",
  "company_registry_id": "S 8 , H AB 31640, I/A 1",
  "nif_cif": null,
  "act_type": "Constitución; Nombramientos",
  "act_type_code": "constitucion; nombramientos",
  "act_text": "Constitución. Comienzo de operaciones: 11.07.25. Objeto social: la compraventa de terrenos de naturaleza rústica o urbana... Capital: 3.100,00 Euros. Nombramientos. Adm. Unico: RUIZ PEREZ JUAN ANGEL. Datos registrales. S 8 , H AB 31640, I/A 1 (12.08.25).",
  "officers_appointed": ["RUIZ PEREZ JUAN ANGEL (Administrador Único)"],
  "officers_removed": [],
  "sole_shareholder": null,
  "capital_amount_eur": 3100,
  "registered_address": "C/ FRAY LUIS DE LEON, 20-REFERENCIA CATASTRAL 3000 (RODA (LA))",
  "corporate_purpose": "la compraventa de terrenos de naturaleza rústica o urbana, urbanización de los mismos, construcción y promoción de locales comerciales...",
  "incorporation_date": "2025-07-11",
  "dissolution_date": null,
  "merger_parties": [],
  "pdf_url": "https://www.boe.es/borme/dias/2025/08/20/pdfs/BORME-A-2025-157-02.pdf",
  "source_url": "https://www.boe.es/diario_borme/txt.php?id=BORME-A-2025-157-02",
  "scraped_at": "2026-09-26T13:30:27.203Z"
}
```

| Field                 | Type   | Description                                                                                  |
|-----------------------|--------|----------------------------------------------------------------------------------------------|
| `act_id`              | string | Unique id for this act (BORME item id + in-item anchor number)                               |
| `publication_date`    | string | Gazette publication date (`YYYY-MM-DD`)                                                      |
| `borme_issue`         | string | The gazette's daily issue number                                                             |
| `section`             | string | `A` (company registrations), `B` (other registry acts) or `C` (legal notices)                |
| `province`            | string | Mercantile-registry province this act was filed under                                        |
| `registry`            | string | The registry's full name ("Registro Mercantil de \<province>")                              |
| `company_name`        | string | Company or entity name                                                                       |
| `company_registry_id` | string | Registry filing reference (hoja / tomo / folio), as published                                |
| `nif_cif`             | string | Tax id, where published — BORME rarely carries this outside insolvency-administrator entries |
| `act_type`            | string | Recognised act type label(s); semicolon-separated when an entry carries more than one        |
| `act_type_code`       | string | Normalised, machine-matchable version of `act_type`                                          |
| `act_text`            | string | The full published text for this entry, unmodified                                           |
| `officers_appointed`  | array  | Officers appointed, each formatted `"NAME (ROLE)"`                                           |
| `officers_removed`    | array  | Officers removed or resigned, each formatted `"NAME (ROLE)"`                                 |
| `sole_shareholder`    | string | Declared sole shareholder (socio único), where present                                       |
| `capital_amount_eur`  | number | Capital amount in EUR, from an incorporation or capital-change entry                         |
| `registered_address`  | string | Registered address, from an incorporation or change-of-address entry                         |
| `corporate_purpose`   | string | Corporate purpose (objeto social), from an incorporation entry                               |
| `incorporation_date`  | string | Operations-start date, where stated                                                          |
| `dissolution_date`    | string | Dissolution date, where stated                                                               |
| `merger_parties`      | array  | Company names named in a merger/absorption or split entry                                    |
| `pdf_url`             | string | Link to the source province/entry PDF page                                                   |
| `source_url`          | string | Link to the source province/entry HTML page                                                  |
| `scraped_at`          | string | ISO-8601 timestamp when this row was scraped                                                 |

A row's `act_type_code` can carry more than one code (e.g. `"ceses_dimisiones; nombramientos"`)
when the same publication both removes and appoints an officer in one entry — this is how BORME
itself publishes it. Fields that don't apply to an entry's act type (e.g. `officers_appointed` on
a change-of-address entry) come back as an empty array or `null` rather than a placeholder.

***

### Resuming a large crawl

Every run emits a `resumeCursor` in its Output. If a large date-range pull stops before it
finishes — because it hit `maxItems`, your spend cap (`maxTotalChargeUsd`), or was aborted — start
a new run with **the same input** plus that `resumeCursor` to continue from where it left off.

- You are **not re-charged** for records the earlier run already delivered.
- Resume within your account's run-retention window — on the free tier, roughly your 10 most
  recent runs. Once the source run is pruned, its `resumeCursor` is no longer valid.
- `resumeCursor` is opaque — supply it unmodified.

***

### FAQ

#### How far back does this go?

BORME has published daily since 2009. Set `startDate` to any date from 2009 onward to include it.

#### Why do some rows have `act_type` as two labels joined with a semicolon?

BORME itself publishes some entries with more than one act in a single paragraph — most commonly
an officer removal followed immediately by a new appointment. Every recognised label present is
listed, in the order it was published.

#### Why is `nif_cif` empty on most rows?

BORME's registry announcements generally don't carry a tax id — it's assigned separately from the
mercantile registration this gazette covers. It appears mainly on insolvency-administrator
appointment entries, where BORME publishes it directly.

#### What happens on a weekend or public holiday?

There's no gazette issue that day, so it's skipped — not treated as an error or a missing date.

***

### Need More Features?

Need additional fields or a different filter? [File an issue](https://console.apify.com/actors/issues) or get in touch.

### Why Use Borme Spain Corporate Acts Gazette Scraper?

- **Structured, not raw text** — officer names, roles, capital amounts and corporate purpose come
  back as typed fields you can query, not a paragraph you have to parse yourself.
- **Full coverage by construction** — every province and every section for a given date comes back
  in the same pass; there's no province or section to add later.
- **Nothing lost** — the raw published text rides alongside the parsed fields on every row, even
  when a clause form isn't one of the common types.

# Actor input Schema

## `sp_intended_usage` (type: `string`):

What will this data feed? E.g. lead lists, KYB checks, price tracking.

## `sp_improvement_suggestions` (type: `string`):

Provide any feedback or suggestions for improvements.

## `sp_contact` (type: `string`):

We'll personally help with your use case. No spam.

## `resumeCursor` (type: `string`):

Leave empty for a fresh crawl. To CONTINUE a previous run where it stopped — without paying again for records you already received — paste the `resumeCursor` value from that run's Output (the run's OUTPUT key). Resume promptly: the previous run's data expires with your account's retention window (free tier: your ~10 most recent runs).

## `startDate` (type: `string`):

First publication date to fetch (inclusive). Defaults to 7 days before today, covering the most recent publication days. Widen to any date back to 2009 for a historical backfill.

## `endDate` (type: `string`):

Last publication date to fetch (inclusive). Defaults to today.

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

Maximum number of corporate-act records to scrape.

## Actor input object example

```json
{
  "sp_intended_usage": "Describe your intended use...",
  "sp_improvement_suggestions": "Share your suggestions here...",
  "sp_contact": "Share your email here...",
  "maxItems": 15
}
```

# Actor output Schema

## `results` (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 = {
    "sp_intended_usage": "Describe your intended use...",
    "sp_improvement_suggestions": "Share your suggestions here...",
    "sp_contact": "Share your email here...",
    "maxItems": 15
};

// Run the Actor and wait for it to finish
const run = await client.actor("jungle_synthesizer/borme-spain-corporate-acts-gazette-scraper").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 = {
    "sp_intended_usage": "Describe your intended use...",
    "sp_improvement_suggestions": "Share your suggestions here...",
    "sp_contact": "Share your email here...",
    "maxItems": 15,
}

# Run the Actor and wait for it to finish
run = client.actor("jungle_synthesizer/borme-spain-corporate-acts-gazette-scraper").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 '{
  "sp_intended_usage": "Describe your intended use...",
  "sp_improvement_suggestions": "Share your suggestions here...",
  "sp_contact": "Share your email here...",
  "maxItems": 15
}' |
apify call jungle_synthesizer/borme-spain-corporate-acts-gazette-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,jungle_synthesizer/borme-spain-corporate-acts-gazette-scraper"
        }
    }
}
```

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/MZwSHO8NqdvB2SOKT/builds/6z9727mmg9kS0CW1f/openapi.json
