OpenMercantil Companies API
Company reports and registry events
Company reports and registry events
Every API here is available over the APIs.io API and to AI agents over MCP.
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
find_apisBrowse and filter every API in the catalog.get_api_artifactsOne API's artifacts, grouped by type.get_openapiThe primary OpenAPI for this API.find_similar_apisAPIs that look like this one.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.curl "https://apis.io/api/v1/apis/openmercantil-companies-api"
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
openapi: 3.2.0
info:
title: Openmercantil Companies API
contact:
name: OpenMercantil
url: https://openmercantil.es/soporte
email: social@openmercantil.es
termsOfService: https://openmercantil.es/terminos-de-uso
x-refined-note:
- x-account-segment-contract differs across the merged source definitions and was not carried
- x-company-identity-contract differs across the merged source definitions and was not carried
- x-contract-status differs across the merged source definitions and was not carried
- x-corrections differs across the merged source definitions and was not carried
- x-dcat-catalog differs across the merged source definitions and was not carried
- x-language differs across the merged source definitions and was not carried
- x-methodology differs across the merged source definitions and was not carried
- x-publisher differs across the merged source definitions and was not carried
- x-rate-limit differs across the merged source definitions and was not carried
- x-sources differs across the merged source definitions and was not carried
- x-spatial differs across the merged source definitions and was not carried
- x-temporal differs across the merged source definitions and was not carried
version: '1.0'
description: 'Operations tagged Companies across 3 of this provider''s published API definitions: openmercantil-openapi-1.9.3.json, openmercantil-openapi.yml, openmercantil-risk-signals-api-openapi.yml. Each path carries the servers of the definition it was published in.'
servers:
- url: https://openmercantil.es
description: Production
tags:
- name: Companies
description: Company reports and registry events
paths:
/api/v1/company/{slug}:
get:
security:
- {}
- apiKey: []
- bearerAuth: []
x-api-credential-scope: companies:read
operationId: getCompanyBySlug
tags:
- Companies
summary: Get a company report
description: Return the structured company report only after company_public_v2 admits a corporate identity. A safe historical alias is resolved internally and reported through Content-Location; absent, personal or quarantined identities are neutral 404 responses and projection unavailability is 503.
parameters:
- name: slug
in: path
required: true
schema:
type: string
example: mercadona-sa
description: Company slug.
- $ref: '#/components/parameters/IfNoneMatchHeader'
responses:
'200':
headers:
X-Data-Sources:
$ref: '#/components/headers/XDataSources'
X-Source-Catalog-Version:
$ref: '#/components/headers/XSourceCatalogVersion'
X-Attribution-Required:
$ref: '#/components/headers/XAttributionRequired'
Content-Location:
$ref: '#/components/headers/CompanyContentLocation'
description: Company report
content:
application/json:
schema:
$ref: '#/components/schemas/CompanyReport'
'304':
description: The admitted, attested company report has not changed.
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/TooManyRequests'
'503':
$ref: '#/components/responses/PublicReadUnavailable'
servers:
- url: https://openmercantil.es
description: Production
/api/v1/companies/compare:
get:
security:
- {}
- apiKey: []
- bearerAuth: []
x-api-credential-scope: companies:read
x-company-identity-contract:
projection: company_compare_v1
subject_projection: company_public_v2
cardinality: 2
admission: one bounded batch admission for both requested slugs before either company is exposed
canonical_order: lexicographic by canonical slug; requested_slugs, canonical_slugs and companies remain index-aligned
withheld: neutral 404 with no partial company
unavailable: 503 no-store; never reinterpret as absence
operationId: compareCompanies
x-query-contract:
allowed:
- slugs
unknown: 400 invalid_parameter
non_scalar: 400 invalid_parameter
lexical: 400 invalid_parameter
tags:
- Companies
summary: Compare exactly two admitted companies
description: Returns only the stable company_compare_v1 projection. Both slugs are resolved together against the immutable company_public_v2 sidecar; safe aliases are canonicalized without redirects. The response excludes reports, blobs, officers, account data, scores and inferred relationships.
parameters:
- name: slugs
in: query
required: true
style: form
explode: false
description: Exactly two distinct corporate slugs serialized as slugs=empresa-a,empresa-b.
schema:
type: array
minItems: 2
maxItems: 2
uniqueItems: true
items:
type: string
minLength: 1
maxLength: 240
pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$
- $ref: '#/components/parameters/IfNoneMatchHeader'
responses:
'200':
description: Two admitted companies in stable canonical order
headers:
X-Data-Sources:
$ref: '#/components/headers/XDataSources'
X-Source-Catalog-Version:
$ref: '#/components/headers/XSourceCatalogVersion'
X-Attribution-Required:
$ref: '#/components/headers/XAttributionRequired'
Content-Location:
$ref: '#/components/headers/CompanyCompareContentLocation'
ETag:
$ref: '#/components/headers/EntityTag'
content:
application/json:
schema:
$ref: '#/components/schemas/CompanyCompareResponse'
'304':
description: The generation-bound comparison has not changed
headers:
Content-Location:
$ref: '#/components/headers/CompanyCompareContentLocation'
ETag:
$ref: '#/components/headers/EntityTag'
'400':
description: Malformed pair or both inputs resolve to the same company
content:
application/json:
schema:
$ref: '#/components/schemas/CompanyCompareInvalidRequest'
'404':
description: At least one subject is absent, personal, ambiguous, quarantined or legally withheld
content:
application/json:
schema:
$ref: '#/components/schemas/CompanyCompareNotFound'
'429':
$ref: '#/components/responses/TooManyRequests'
'503':
description: The immutable company comparison projection or its authority is unavailable
headers:
Cache-Control:
description: Projection outages are never cacheable.
schema:
type: string
const: no-store
Retry-After:
description: Seconds to wait before a bounded retry.
schema:
type: integer
minimum: 1
content:
application/json:
schema:
oneOf:
- $ref: '#/components/schemas/ProjectionUnavailableError'
- $ref: '#/components/schemas/CompanyCompareLegalUnavailable'
servers:
- url: https://openmercantil.es
description: Production
/api/v1/datasets/public:
get:
security:
- {}
- apiKey: []
- bearerAuth: []
x-api-credential-scope: companies:read
operationId: listPublicCompanyDownloads
parameters:
- $ref: '#/components/parameters/IfNoneMatchHeader'
tags:
- Companies
summary: List generation-bound public company downloads
description: Lists exactly the three bounded public company downloads admitted by company_public artifact contract 1.1. Every member is reverified through the immutable manifest and SHA-256 ledger before this atomic catalog is emitted. A missing, stale or tampered member makes the whole projection unavailable; raw company tables, local paths and legacy docroot fallbacks are never exposed.
responses:
'200':
description: Atomic catalog of the three admitted public company downloads
headers:
X-Data-Sources:
$ref: '#/components/headers/XDataSources'
X-Source-Catalog-Version:
$ref: '#/components/headers/XSourceCatalogVersion'
X-Attribution-Required:
$ref: '#/components/headers/XAttributionRequired'
ETag:
$ref: '#/components/headers/EntityTag'
content:
application/json:
schema:
$ref: '#/components/schemas/PublicCompanyDownloadCatalog'
'304':
description: The generation-bound download catalog has not changed
headers:
ETag:
$ref: '#/components/headers/EntityTag'
'429':
$ref: '#/components/responses/TooManyRequests'
'503':
$ref: '#/components/responses/PublicReadUnavailable'
servers:
- url: https://openmercantil.es
description: Production
/api/v1/company/{slug}/events:
get:
security:
- {}
- apiKey: []
- bearerAuth: []
x-api-credential-scope: companies:read
operationId: getCompanyBySlugEvents
tags:
- Companies
summary: Get paginated company events
description: Return BORME events for a known company slug, optionally filtered by calendar year. The closed scalar query contract rejects unknown names, arrays and malformed integer values with 400; valid integers outside their bounds return 422. If year is omitted, the server freezes the current UTC year for the request. Historical coverage starts at 1900 and year must be less than or equal to the current UTC year; there is no fixed calendar ceiling.
x-query-contract:
allowed:
- year
- page
- page_size
unknown: 400 invalid_parameter
non_scalar: 400 invalid_parameter
lexical: 400 invalid_parameter
range: 422 validation_failed
parameters:
- name: slug
in: path
required: true
schema:
type: string
example: mercadona-sa
- name: year
in: query
required: false
description: Calendar year from 1900 through the current UTC year (year <= current UTC year). Defaults dynamically to the current UTC year.
schema:
type: integer
minimum: 1900
x-maximum-dynamic: current_utc_year
example: 2026
- name: page
in: query
required: false
schema:
type: integer
minimum: 1
maximum: 1000
default: 1
- name: page_size
in: query
required: false
schema:
type: integer
minimum: 1
maximum: 100
default: 50
- $ref: '#/components/parameters/IfNoneMatchHeader'
responses:
'200':
headers:
X-Data-Sources:
$ref: '#/components/headers/XDataSources'
X-Source-Catalog-Version:
$ref: '#/components/headers/XSourceCatalogVersion'
X-Attribution-Required:
$ref: '#/components/headers/XAttributionRequired'
description: Paginated event list
content:
application/json:
schema:
$ref: '#/components/schemas/CompanyEventsResponse'
'304':
description: The generation-bound event page has not changed.
'404':
$ref: '#/components/responses/NotFound'
'400':
$ref: '#/components/responses/BadRequest'
'422':
description: A validly typed year, page or page_size is outside its documented range
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalServerError'
'503':
$ref: '#/components/responses/PublicReadUnavailable'
servers:
- url: https://openmercantil.es
description: Production
/api/v1/company/{slug}/timeline:
get:
security:
- {}
- apiKey: []
- bearerAuth: []
x-api-credential-scope: companies:read
operationId: getCompanyBySlugTimeline
tags:
- Companies
summary: Get unified multi-source company timeline
description: Fail-closed derived route. Return chronological events from the exact hash-attested BORME company report and the generation/company-bound PLACSP projection. BDNS coverage is explicitly unavailable_generation_bound_projection_missing and no BDNS row, empty-list claim or fallback is emitted. If either available authority cannot be verified, the route returns 503 without reading or caching raw source data.
parameters:
- name: slug
in: path
required: true
schema:
type: string
example: banco-santander-s-a
description: Company slug.
responses:
'200':
headers:
X-Data-Sources:
$ref: '#/components/headers/XDataSources'
X-Source-Catalog-Version:
$ref: '#/components/headers/XSourceCatalogVersion'
X-Attribution-Required:
$ref: '#/components/headers/XAttributionRequired'
description: Multi-source timeline
content:
application/json:
schema:
type: object
required:
- slug
- count
- sources
- events
- coverage
properties:
slug:
type: string
count:
type: integer
maximum: 100
sources:
type: array
items:
type: string
enum:
- borme
- placsp
minItems: 2
maxItems: 2
example:
- borme
- placsp
events:
type: array
items:
type: object
properties:
date:
type: string
format: date
category:
type: string
enum:
- borme
- contratos
type:
type: string
title:
type: string
amount_eur:
type:
- number
- 'null'
source_slug:
type: string
enum:
- borme
- placsp
source_url:
type: string
confidence:
type: string
enum:
- high
- medium
- low
amount_semantics:
type: string
additionalProperties: false
coverage:
type: object
required:
- borme
- placsp
- bdns
properties:
borme:
type: string
placsp:
type: string
bdns:
type: string
const: unavailable_generation_bound_projection_missing
additionalProperties: false
_disclaimer:
type: string
'404':
$ref: '#/components/responses/NotFound'
'503':
$ref: '#/components/responses/LegalLayerUnavailable'
'429':
$ref: '#/components/responses/TooManyRequests'
servers:
- url: https://openmercantil.es
description: Production
/api/v1/company/{slug}/officers:
get:
security:
- {}
- apiKey: []
- bearerAuth: []
x-api-credential-scope: companies:read
operationId: getCompanyBySlugOfficers
tags:
- Companies
summary: Get current and historical company officers
description: Return at most 500 officer mentions from the same cached, policy-filtered company projection used by the canonical company route. The JSON body is capped at 1 MiB. Persons are documentary mentions only — no DNI, contact data or personal address.
x-rate-limit: plan policy (see info.x-rate-limit)
parameters:
- name: slug
in: path
required: true
schema:
type: string
example: banco-santander-s-a
responses:
'200':
headers:
X-Data-Sources:
$ref: '#/components/headers/XDataSources'
X-Source-Catalog-Version:
$ref: '#/components/headers/XSourceCatalogVersion'
X-Attribution-Required:
$ref: '#/components/headers/XAttributionRequired'
description: Officer list
content:
application/json:
schema:
$ref: '#/components/schemas/OfficerList'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/TooManyRequests'
'503':
description: Bounded cached officer projection unavailable
content:
application/json:
schema:
$ref: '#/components/schemas/OfflineProjectionError'
servers:
- url: https://openmercantil.es
description: Production
/api/v1/company/{slug}/contracts:
get:
security:
- {}
- apiKey: []
- bearerAuth: []
x-api-credential-scope: companies:read
operationId: getCompanyBySlugContracts
x-query-contract:
allowed:
- limit
unknown: 400 invalid_parameter
non_scalar: 400 invalid_parameter
lexical: 400 invalid_parameter
range: 422 validation_failed
tags:
- Companies
summary: Get PLACSP procurement notices linked to a legal entity
description: Requires the legal-first PLACSP v3 projection, including typed budget, estimate and award fields plus corporate supplier edges. It never falls back to the legacy untyped table and never sums mixed monetary concepts. A CIF link is documentary and does not prove payment or executed spend.
x-rate-limit: plan policy (see info.x-rate-limit)
parameters:
- name: slug
in: path
required: true
schema:
type: string
example: banco-santander-s-a
- name: limit
in: query
required: false
schema:
type: integer
minimum: 1
maximum: 100
default: 30
responses:
'200':
headers:
X-Data-Sources:
$ref: '#/components/headers/XDataSources'
X-Source-Catalog-Version:
$ref: '#/components/headers/XSourceCatalogVersion'
X-Attribution-Required:
$ref: '#/components/headers/XAttributionRequired'
description: Contracts list
content:
application/json:
schema:
$ref: '#/components/schemas/CompanyProcurementResponse'
'400':
$ref: '#/components/responses/BadRequest'
'422':
$ref: '#/components/responses/ValidationFailed'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalServerError'
'503':
$ref: '#/components/responses/PublicReadUnavailable'
servers:
- url: https://openmercantil.es
description: Production
/api/v1/company/{slug}/procurement:
get:
operationId: getCompanyBySlugProcurement
x-query-contract:
allowed: []
unknown: 400 invalid_parameter
non_scalar: 400 invalid_parameter
lexical: 400 invalid_parameter
tags:
- Companies
summary: Alias of /contracts
description: Documentary alias for /contracts endpoint. Same payload and projection requirements; `_alias_of` contains the canonical route.
x-rate-limit: plan policy (see info.x-rate-limit)
parameters:
- name: slug
in: path
required: true
schema:
type: string
responses:
'200':
description: Procurement awards (alias of contracts)
content:
application/json:
schema:
$ref: '#/components/schemas/CompanyProcurementResponse'
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/TooManyRequests'
'500':
$ref: '#/components/responses/InternalServerError'
'503':
description: Legal-first PLACSP projection unavailable
servers:
- url: https://openmercantil.es
description: Production
/api/v1/company/{slug}/grants:
get:
security:
- {}
- apiKey: []
- bearerAuth: []
x-api-credential-scope: companies:read
operationId: getCompanyBySlugGrants
x-query-contract:
allowed:
- limit
unknown: 400 invalid_parameter
non_scalar: 400 invalid_parameter
lexical: 400 invalid_parameter
range: 422 validation_failed
tags:
- Companies
summary: Get BDNS public grants
description: Read only company_integrations_public_v1 after company_public_v2 admission. Returns up to 200 attested BDNS rows and never queries the canonical grants table. Monetary values are awarded amounts in integer cents, never payments; ambiguous raw zero is null. Empty is complete bounded-projection coverage, not proof of absence upstream.
parameters:
- $ref: '#/components/parameters/CompanySlugPath'
- name: limit
in: query
required: false
schema:
type: integer
minimum: 1
maximum: 200
default: 100
- $ref: '#/components/parameters/IfNoneMatchHeader'
responses:
'200':
headers:
X-Data-Sources:
$ref: '#/components/headers/XDataSources'
X-Source-Catalog-Version:
$ref: '#/components/headers/XSourceCatalogVersion'
X-Attribution-Required:
$ref: '#/components/headers/XAttributionRequired'
Content-Location:
$ref: '#/components/headers/CompanyContentLocation'
ETag:
$ref: '#/components/headers/EntityTag'
Cache-Control:
$ref: '#/components/headers/PrivateRevalidationCacheControl'
description: Grants list
content:
application/json:
schema:
$ref: '#/components/schemas/CompanyGrantsResponse'
'304':
description: The admitted company, projection generation and legal envelope have not changed
headers:
X-Data-Sources:
$ref: '#/components/headers/XDataSources'
X-Source-Catalog-Version:
$ref: '#/components/headers/XSourceCatalogVersion'
X-Attribution-Required:
$ref: '#/components/headers/XAttributionRequired'
Content-Location:
$ref: '#/components/headers/CompanyContentLocation'
ETag:
$ref: '#/components/headers/EntityTag'
Cache-Control:
$ref: '#/components/headers/PrivateRevalidationCacheControl'
'400':
$ref: '#/components/responses/BadRequest'
'422':
$ref: '#/components/responses/ValidationFailed'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/TooManyRequests'
'503':
$ref: '#/components/responses/PublicReadUnavailable'
servers:
- url: https://openmercantil.es
description: Production
/api/v1/company/{slug}/ip:
get:
operationId: getCompanyBySlugIp
tags:
- Companies
summary: Get policy-gated aggregated trademarks and patents
description: Fail-closed aggregate over OEPM/EUIPO/EPO data. Because upstream provenance cannot currently be separated in the aggregate, the route returns 503 until an exact aggregate-dataset decision authorizes every component and derivative use.
parameters:
- name: slug
in: path
required: true
schema:
type: string
responses:
'200':
description: Trademarks + patents counts with states legend
content:
application/json:
schema:
type: object
properties:
slug:
type: string
trademarks:
type: object
properties:
count:
type: integer
active:
type: integer
sources:
type: array
items:
type: string
example:
- OEPM
- EUIPO
patents:
type: object
properties:
count:
type: integer
active:
type: integer
sources:
type: array
items:
type: string
example:
- OEPM
- EPO
- WIPO
states_legend:
type: object
additionalProperties:
type: string
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/TooManyRequests'
'503':
$ref: '#/components/responses/LegalLayerUnavailable'
servers:
- url: https://openmercantil.es
description: Production
/api/v1/company/{slug}/sources:
get:
security:
- {}
- apiKey: []
- bearerAuth: []
x-api-credential-scope: companies:read
operationId: getCompanyBySlugSources
x-query-contract:
allowed: []
unknown: 400 invalid_parameter
non_scalar: 400 invalid_parameter
lexical: 400 invalid_parameter
tags:
- Companies
summary: Get bounded public integration coverage for a company
description: Return the four generation-bound company integration sources (BDNS, CNMV, TED and Wikidata) with explicit available/empty coverage and projection-bound license metadata. It never probes BORME, PLACSP, OEPM, GLEIF, sanctions, raw helpers or connector telemetry. Empty never proves upstream absence.
parameters:
- $ref: '#/components/parameters/CompanySlugPath'
- $ref: '#/components/parameters/IfNoneMatchHeader'
responses:
'200':
headers:
X-Data-Sources:
$ref: '#/components/headers/XDataSources'
X-Source-Catalog-Version:
$ref: '#/components/headers/XSourceCatalogVersion'
X-Attribution-Required:
$ref: '#/components/headers/XAttributionRequired'
Content-Location:
$ref: '#/components/headers/CompanyContentLocation'
ETag:
$ref: '#/components/headers/EntityTag'
Cache-Control:
$ref: '#/components/headers/PrivateRevalidationCacheControl'
description: Generation-bound coverage for exactly four safe company integrations
content:
application/json:
schema:
$ref: '#/components/schemas/CompanySourcesResponse'
'304':
description: The admitted company, projection generation and legal envelope have not changed
headers:
X-Data-Sources:
$ref: '#/components/headers/XDataSources'
X-Source-Catalog-Version:
$ref: '#/components/headers/XSourceCatalogVersion'
X-Attribution-Required:
$ref: '#/components/headers/XAttributionRequired'
Content-Location:
$ref: '#/components/headers/CompanyContentLocation'
ETag:
$ref: '#/components/headers/EntityTag'
Cache-Control:
$ref: '#/components/headers/PrivateRevalidationCacheControl'
'400':
$ref: '#/components/responses/BadRequest'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/TooManyRequests'
'503':
$ref: '#/components/responses/PublicReadUnavailable'
servers:
- url: https://openmercantil.es
description: Production
/api/v1/company/{slug}/sanctions:
get:
operationId: getCompanyBySlugSanctions
tags:
- Companies
summary: Get policy-gated sanctions dataset
description: This route is fail-closed. It returns data only when the exact sanctions dataset has a valid public decision, license metadata and identity policy in the active source catalog. OpenSanctions is currently in review, so the route returns 503 without reading or serializing its payload.
parameters:
- name: slug
in: path
required: true
schema:
type: string
responses:
'200':
description: Sanctions list when the exact dataset is authorized
content:
application/json:
schema:
$ref: '#/components/schemas/CompanySanctionsResponse'
'404':
$ref: '#/components/responses/NotFound'
'429':
$ref: '#/components/responses/TooManyRequests'
'503':
$ref: '#/components/responses/LegalLayerUnavailable'
servers:
- url: https://openmercantil.es
description: Production
/api/v1/empresa/{slug}/facts:
get:
security:
- {}
- apiKey: []
- bearerAuth: []
x-api-credential-scope: companies:read
operationId: getEmpresaBySlugFacts
x-query-contract:
allowed:
- limit
unknown: 400 invalid_parameter
non_scalar: 400 invalid_parameter
lexical: 400 invalid_parameter
range: 422 validation_failed
tags:
- Companies
summary: Get extracted BORME facts for a company
description: Return structured facts extracted from BORME publications grouped by type (appointments, removals, capital changes, etc.). Spanish-friendly alias of /company.
parameters:
- name: slug
in: path
required: true
schema:
type: string
- name: limit
in: query
required: false
schema:
type: integer
minimum: 1
maximum: 200
default: 50
- $ref: '#/components/parameters/IfNoneMatchHeader'
responses:
'200':
headers:
X-Data-Sources:
$ref: '#/components/headers/XDataSources'
X-Source-Catalog-Version:
$ref: '#/components/headers/XSourceCatalogVersion'
X-Attribution-Required:
$ref: '#/components/headers/XAttributionRequired'
description: Grouped facts
content:
applica
# --- truncated at 32 KB (148 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/openmercantil/refs/heads/main/openapi/openmercantil-companies-api-openapi.yml