BORME API

BORME API clients for Python and TypeScript

Two client libraries for BORME API, an independent service providing data derived from BORME notices and other public registries through a REST API. Both packages are called bormeapi, are released under the MIT licence, and start at version 1.0.0.

Python quick start · TypeScript quick start · Your API key · What the clients cover · Pagination · Errors and retries · API reference

Python quick start

pip install bormeapi
from bormeapi import BormeClient
client = BormeClient("YOUR_API_KEY")   # or BormeClient() with BORME_API_KEY set
company = client.company_by_nif("A46103834")
print(company["company_name"], company["status"])
for event in client.iter_events(province="MADRID", act_type="INCORPORATION", max_items=20):
    print(event["date"], event["company_name"])

Pass your key explicitly, or use client = BormeClient() after setting BORME_API_KEY: the variable is read only when no key is passed.

TypeScript quick start

npm install bormeapi
import { BormeClient } from "bormeapi";
const client = new BormeClient({ apiKey: process.env.BORME_API_KEY });
const company = await client.companyByNif("A46103834");
console.log(company.company_name, company.status);
for await (const ev of client.iterEvents({ province: "MADRID", act_type: "INCORPORATION" }, { maxItems: 20 }))
  console.log(ev.date, ev.company_name);

CommonJS works too: const { BormeClient } = require("bormeapi");

Your API key

Get a free key on your account page. The free plan allows 50 requests a day and provides access to the last 7 days of history; some endpoints and filters require a paid plan (see pricing). The key travels in the X-API-Key header only.

Do not put your key in code that runs in a visitor's browser: anyone could read it there.

Get an API key

What the clients cover

Both clients offer the same operations. Python uses snake_case method names, TypeScript camelCase.

Python

With include_inferred=True, company() and company_events() may also return a CNAE-2009 division inferred by a language model from the company's stated corporate purpose (objeto social), when it meets the confidence threshold (0.9 by default) and no CNAE code appears on the company card (for company()) or in any of the event's acts (for company_events()) (cnae_source jev, details in cnae_inference). It describes the stated purpose, not the company's verified activity, and is not a code published in the BORME. If include_inferred is omitted or set to False, no inferred values are included.

Responses are plain dicts typed with TypedDict (bormeapi.models), so new fields the API adds reach you without an upgrade.

TypeScript

With { include_inferred: true }, company() and companyEvents() may also return a CNAE-2009 division inferred by a language model from the company's stated corporate purpose (objeto social), when it meets the confidence threshold (0.9 by default) and no CNAE code appears on the company card (for company()) or in any of the event's acts (for companyEvents()) (cnae_source jev, details in cnae_inference). It describes the stated purpose, not the company's verified activity, and is not a code published in the BORME. If include_inferred is omitted or set to false, no inferred values are included.

Response fields keep the API's snake_case names, so the API reference applies as written.

In both clients

Pagination

iter_events (Python) and iterEvents (TypeScript) request pages of up to 200 events and stop at the last page, after max_items / maxItems, or when the offset would pass 10,000 (the API limit). For larger result sets, split the date range. Every page is one request and counts against your quota.

Errors and retries

HTTP error responses raise (Python) or throw (TypeScript) ApiError or one of its subclasses, with status, code (the API error code when there is one), the message (message in Python, apiMessage in TypeScript), body and headers:

A 429 or 503 is retried up to three times (max_retries=3 in Python, maxRetries: 3 in TypeScript) only when Retry-After is valid and asks for a wait of at most 60 seconds (max_retry_wait=60, maxRetryWaitSeconds: 60); otherwise the error is raised at once. A 503 is retried only for GET and DELETE. A 429 without Retry-After means the daily quota is used up: it resets at 00:00 UTC, so it is raised at once, with limit and upgrade_url (upgradeUrl in TypeScript).

from bormeapi import NotFoundError
try:
    client.company("mercadona-sl")
except NotFoundError as e:
    print(e.message, e.suggestions)
import { NotFoundError } from "bormeapi";
try {
  await client.company("mercadona-sl");
} catch (e) {
  if (e instanceof NotFoundError) console.log(e.apiMessage, e.suggestions);
}

Requests using an old slug for a renamed or merged company are redirected to the current slug. The clients follow up to three redirects, only to the same origin, so the key is never sent elsewhere. The TypeScript client can do this when the runtime exposes Location (Node, Deno, Bun); in browsers, an opaque redirect throws TransportError.

API reference

Every field, filter and error code is described in the API reference (in Spanish: documentación de la API). The packages: bormeapi on PyPI · bormeapi on npm.

Questions about an integration? Write to us; we answer personally, usually the same working day.

build 2026.11.13·0e6b8884