Company API

Spanish company registry API, built on the BORME

Search a company by tax ID (CIF), registry sheet or name and get, as JSON, its status, capital, current officers and latest filing, with a link to the official gazette it comes from. No PDF parsing on your side.

Access status

Access is open

Create your developer account, confirm your email and enable two-factor authentication (mandatory) to create your key. The library, calculators and deadlines do not use balance; companies and assistant come with 100 trial queries, no card needed.

Access will be for verified businesses worldwide.

Who it is for

  • Teams building a CRM, an ERP or an operations tool who want to complete the profile of a Spanish company from its tax ID.
  • Anyone doing due diligence or vendor and customer checks who needs a company’s status and who appears among its officers.
  • Data journalism and research following the Commercial Registry’s news day by day.
  • Accounting and advisory firms and law firms with a technical team that automate repetitive checks.

What you can do

Search by tax ID, registry sheet or name

One search understands a CIF, a registry sheet (“M 167931”) or a name, and the response says in tipo how it understood it. You can filter by province and by CNAE division (two digits) of the published corporate purpose.

Company profile

Status (active, insolvency, dissolved or struck off, with its date), capital in euro cents, current officers, number of filings and the latest filing with its gazette and official PDF.

People, with a homonym warning

Search a name and get the companies where it appears. The BORME does not publish national ID numbers: the response flags possible homonyms and never labels a person, it only gives the published fact.

News and statistics

The days with a gazette in a month, the detail of one day by province with the official PDF of each gazette, and counts of acts by type and filings by province (up to 31 days per query).

How far the data goes

GET /v1/dev/estado returns the last day loaded and how many days and filings there are, so you can tell whether “no results” means that or a delay.

The operations

  • GET/empresas

    Search Spanish companies in the BORME by tax ID (CIF), registry sheet or name Details (Spanish)

    1 euro cent per query
  • GET/empresas/{empresaId}

    Company profile: status, capital, current officers and latest filing Details (Spanish)

    1 euro cent per query
  • GET/personas

    Search people in the BORME by name, with a homonym warning Details (Spanish)

    1 euro cent per query
  • GET/personas/{slug}

    Person profile: the companies where the name appears Details (Spanish)

    1 euro cent per query
  • GET/provincias

    Provinces with at least one BORME gazette loaded Details (Spanish)

    Free
  • GET/boletines

    Days with a BORME gazette loaded in a month Details (Spanish)

    1 euro cent per query
  • GET/boletines/{fecha}

    What the BORME published on a date, by province, with the official PDF Details (Spanish)

    1 euro cent per query
  • GET/estadisticas

    Acts by type and filings by province over up to 31 days Details (Spanish)

    1 euro cent per query
  • GET/estado

    How far the BORME is loaded Details (Spanish)

    Free

Request and response examples

The examples read your key from the JURILIA_API_KEY environment variable.

Search a company by name

With the province filter. Replace q with a tax ID or a registry sheet and it is understood just the same.

curl

curl "https://api.jurilia.com/v1/dev/empresas?q=acme&provincia=Madrid" \
  -H "Authorization: Bearer $JURILIA_API_KEY"

Python

import os
import requests

r = requests.get(
    "https://api.jurilia.com/v1/dev/empresas",
    headers={"Authorization": f"Bearer {os.environ['JURILIA_API_KEY']}"},
    params={"q":"acme","provincia":"Madrid"},
    timeout=30,
)
r.raise_for_status()
print(r.json())

JavaScript

const url = new URL("https://api.jurilia.com/v1/dev/empresas");
url.search = new URLSearchParams({"q":"acme","provincia":"Madrid"});
const r = await fetch(url, {
  headers: { Authorization: `Bearer ${process.env.JURILIA_API_KEY}` },
});
if (!r.ok) throw new Error(`HTTP ${r.status}`);
console.log(await r.json());

Response (the shape; the values are examples)

{
  "tipo": "nombre",
  "sugerencia": null,
  "empresas": [
    {
      "id": "1234567",
      "denominacion": "ACME SOCIEDAD LIMITADA",
      "provincia": "Madrid",
      "hoja": "M 167931",
      "titular": "sociedad",
      "primeraPublicacion": "2010-03-15",
      "ultimaPublicacion": "2026-06-02",
      "concursalPublicadoEn": null,
      "disolucionPublicadaEn": null,
      "extincionPublicadaEn": null,
      "nombreQueCasa": null
    }
  ]
}

The values are illustrative so you can see the exact shape of the response; they are not data from a real query.

A company profile

The identifier is the one the search returns.

curl

curl "https://api.jurilia.com/v1/dev/empresas/1234567" \
  -H "Authorization: Bearer $JURILIA_API_KEY"

Python

import os
import requests

r = requests.get(
    "https://api.jurilia.com/v1/dev/empresas/1234567",
    headers={"Authorization": f"Bearer {os.environ['JURILIA_API_KEY']}"},
    timeout=30,
)
r.raise_for_status()
print(r.json())

JavaScript

const url = new URL("https://api.jurilia.com/v1/dev/empresas/1234567");
const r = await fetch(url, {
  headers: { Authorization: `Bearer ${process.env.JURILIA_API_KEY}` },
});
if (!r.ok) throw new Error(`HTTP ${r.status}`);
console.log(await r.json());

Response (the shape; the values are examples)

{
  "id": "1234567",
  "denominacion": "ACME SOCIEDAD LIMITADA",
  "provincia": "Madrid",
  "hoja": "M 167931",
  "titular": "sociedad",
  "situacion": "activa",
  "situacionFecha": null,
  "constitucionFecha": "2010-03-15",
  "primeraPublicacion": "2010-03-15",
  "ultimaPublicacion": "2026-06-02",
  "capitalCentimos": 300000,
  "totalInscripciones": 14,
  "denominaciones": [],
  "cargosVigentes": [{ "cargo": "Administrador único", "nombre": "…" }],
  "ultimaInscripcion": {
    "fecha": "2026-06-02",
    "boletin": "BORME-A-2026-104-12",
    "urlPdf": "https://www.boe.es/borme/dias/2026/06/02/pdfs/…pdf",
    "actos": [{ "tipo": "cambio_de_administradores", "etiqueta": null }]
  }
}

The values are illustrative so you can see the exact shape of the response; they are not data from a real query.

The news of one day

The provincial gazettes of a date, each with its official PDF.

curl

curl "https://api.jurilia.com/v1/dev/boletines/2026-09-30" \
  -H "Authorization: Bearer $JURILIA_API_KEY"

Python

import os
import requests

r = requests.get(
    "https://api.jurilia.com/v1/dev/boletines/2026-09-30",
    headers={"Authorization": f"Bearer {os.environ['JURILIA_API_KEY']}"},
    timeout=30,
)
r.raise_for_status()
print(r.json())

JavaScript

const url = new URL("https://api.jurilia.com/v1/dev/boletines/2026-09-30");
const r = await fetch(url, {
  headers: { Authorization: `Bearer ${process.env.JURILIA_API_KEY}` },
});
if (!r.ok) throw new Error(`HTTP ${r.status}`);
console.log(await r.json());

Response (the shape; the values are examples)

{
  "fecha": "2026-09-30",
  "numero": 184,
  "documentos": 52,
  "inscripciones": 1402,
  "provincias": [
    {
      "identificador": "BORME-A-2026-184-28",
      "provincia": "Madrid",
      "urlPdf": "https://www.boe.es/borme/dias/2026/09/30/pdfs/…pdf",
      "anuncios": 311
    }
  ]
}

The values are illustrative so you can see the exact shape of the response; they are not data from a real query.

Why you can trust what it returns

The source, on every profile

Each profile carries the gazette identifier and the official boe.es PDF of its latest filing.

Data from the gazette itself

It is what the Commercial Registry Gazette (BORME) publishes, with its date and its gazette.

“Not found” is an answer

If it is not in what is loaded, 404; and /estado says how far what is loaded goes. A profile is never made up.

Per-query price, no sales call

1 euro cent per query from a prepaid balance with no expiry and no monthly fee.

Limits and what it does not do

  • Only what the BORME publishes: incorporations, appointments and removals, capital, insolvency, dissolutions and similar. No annual accounts and no turnover data.
  • It is information published in the gazette, not a registry certificate.
  • Equal names can be different people: the response flags it with homonimos.
  • 120 calls per minute per key.
  • The /estadisticas interval is capped at 31 days; if it is cut, the response says so.

Price

The first 100 company and assistant queries are a one-time trial, shared between the two. After that, 1 euro cent per query, from a prepaid balance bought in packages, with no subscription and no expiry. With no balance the call is not served (402) and no debt is ever created.

Authentication and errors

Every call carries the key of your developer account in the header Authorization: Bearer iuris_sk_…. The base address is https://api.jurilia.com. There is a limit of 120 calls per minute per key, with the headers X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset on every response. A key can carry an allow-list of IPs or networks (CIDR).

Failures come as JSON with a stable code: 401 (missing or invalid key), 402 (no balance: not served and not charged), 403 (IP not allowed), 409 (a datum that decides the calculation is missing: not charged) and 429 (too many calls in a row).

Frequently asked questions

Can I look a company up by its tax ID?
Yes. GET /v1/dev/empresas?q= accepts a CIF, a registry sheet or a name, and the response states in the tipo field how it understood it.
Where does the data come from?
From the Commercial Registry Gazette (BORME), published in the BOE. Each profile carries the gazette and the official PDF its latest filing comes from.
How much does a query cost?
The first 100 company and assistant queries are a one-time trial, shared between the two. After that, 1 euro cent per query, from a prepaid balance bought in packages, with no subscription and no expiry. With no balance the call is not served (402) and no debt is ever created. The service routes (check the key, load status and provinces) are free.
How do I know the data is up to date?
GET /v1/dev/estado returns the last day with BORME loaded and how many days and filings there are. Check it before trusting a “no results”.
Can I use it to verify a customer or a supplier?
You can look up the published status and officers of a company with their source. It is gazette information, not a Commercial Registry certificate, and the due-diligence decision remains yours.