Work with this as data
Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
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.
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/openmercantil-system-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
OpenAPI Specification
openapi: 3.2.0
info:
title: Openmercantil System 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 System across 2 of this provider''s published API definitions: openmercantil-openapi-1.9.3.json, openmercantil-openapi.yml. Each path carries the servers of the definition it was published in.'
servers:
- url: https://openmercantil.es
description: Production
tags:
- name: System
description: Service health and metadata
paths:
/api/v1/health:
get:
security:
- {}
- apiKey: []
- bearerAuth: []
x-api-credential-scope: companies:read
operationId: getHealth
parameters:
- $ref: '#/components/parameters/IfNoneMatchHeader'
tags:
- System
summary: Service health
description: Return service status and BORME freshness from exactly one bounded global_counters_v1 offline projection. Its ETag is also bound to the shared asv1 generation used by CCAA, sector and sources, with 60-second must-revalidate caching. A cold request never opens SQLite, validates person/company sidecars, scans artifact directories, probes CSV files or rebuilds counters. Missing, legacy, malformed or future-dated projection bytes return 503.
x-rate-limit: plan policy (see info.x-rate-limit)
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'
ETag:
$ref: '#/components/headers/EntityTag'
X-OpenMercantil-Stats-Generation:
$ref: '#/components/headers/StatsGeneration'
Cache-Control:
schema:
type: string
const: public, max-age=60, must-revalidate
description: Health response
content:
application/json:
schema:
$ref: '#/components/schemas/HealthResponse'
'304':
description: The exact offline health representation and shared stats generation have not changed
headers:
ETag:
$ref: '#/components/headers/EntityTag'
X-OpenMercantil-Stats-Generation:
$ref: '#/components/headers/StatsGeneration'
Cache-Control:
schema:
type: string
const: public, max-age=60, must-revalidate
'429':
$ref: '#/components/responses/TooManyRequests'
'503':
$ref: '#/components/responses/PublicReadUnavailable'
servers:
- url: https://openmercantil.es
description: Production
/api/v1/stats:
get:
security:
- {}
- apiKey: []
- bearerAuth: []
x-api-credential-scope: companies:read
operationId: getStats
parameters:
- $ref: '#/components/parameters/IfNoneMatchHeader'
tags:
- System
summary: Published public-dataset counters
description: Return the number of legal entities actually published in the active company_public_v2 sidecar, plus an optional offline person-mention approximation. It never exposes the raw 2.8M-row companies population and never runs a request-path COUNT. Sidecar unavailability is 503, not a zero/null company count.
x-rate-limit: plan policy (see info.x-rate-limit)
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: Stats response
content:
application/json:
schema:
type: object
properties:
total_companies:
type: integer
minimum: 1
description: company_public_projection_state.row_count for the active bundle
total_persons_approx:
type:
- integer
- 'null'
example: 970000
person_count_source:
type:
- string
- 'null'
enum:
- person_public_v1
- null
description: Null means person authority unavailable; never reinterpret as zero.
person_public_source_generation:
type:
- string
- 'null'
pattern: ^cpv2-[a-f0-9]{64}$
built_at:
type: string
format: date-time
timestamp:
type: string
format: date-time
version:
type: string
const: '1.2'
count_source:
type: string
const: company_public_v2
required:
- total_companies
- total_persons_approx
- person_count_source
- person_public_source_generation
- built_at
- timestamp
- version
- count_source
additionalProperties: false
'304':
description: The company-public generation and bounded statistics representation have not changed.
'429':
$ref: '#/components/responses/TooManyRequests'
'503':
$ref: '#/components/responses/PublicReadUnavailable'
servers:
- url: https://openmercantil.es
description: Production
components:
headers:
EntityTag:
description: Strong generation-bound entity tag for conditional GET.
schema:
type: string
pattern: ^"[a-f0-9]{64}"$
XAttributionRequired:
description: Optional. When present, comma-separated public source aliases whose attribution terms must accompany reuse.
schema:
type: string
minLength: 1
pattern: ^[a-z0-9][a-z0-9_.-]*(,[a-z0-9][a-z0-9_.-]*)*$
example: placsp
XSourceCatalogVersion:
description: Mandatory on every successful public GET. Exact version of the legal source catalog used to authorize the response.
schema:
type: string
minLength: 1
example: 2026-07-12.2
XDataSources:
description: Comma-separated aliases from the active public source catalog that contributed to the response. Omitted only when a valid exact filter returns an empty representation with zero contributing sources.
schema:
type: string
minLength: 1
pattern: ^[a-z0-9][a-z0-9_.-]*(,[a-z0-9][a-z0-9_.-]*)*$
example: borme,placsp
StatsGeneration:
description: Exact shared generation of the active CCAA, sector, sources and global-counters bundle.
schema:
type: string
pattern: ^asv1-[a-f0-9]{64}$
schemas:
ProjectionUnavailableError:
type: object
description: Fail-closed projection outage. Clients must not reinterpret this response as an empty or negative result.
required:
- error
- detail
- projection
properties:
error:
type: string
const: projection_unavailable
detail:
type: string
projection:
type: string
additionalProperties: false
HealthResponse:
type: object
required:
- status
- service
- version
- projection
- projection_generation
- generated_at
- artifacts_age_hours
- latest_borme_processed
- companies_indexed_approx
- total_events_approx
- count_source
- features
- degraded
properties:
status:
type: string
enum:
- ok
- stale
- error
service:
type: string
const: openmercantil
version:
type: string
projection:
type: string
const: global_counters_v1
projection_generation:
type: string
pattern: ^gc1-[a-f0-9]{64}$
generated_at:
type: string
format: date-time
artifacts_age_hours:
type: number
minimum: 0
latest_borme_processed:
type: string
format: date
companies_indexed_approx:
type: integer
minimum: 0
total_events_approx:
type: integer
minimum: 0
count_source:
type: string
const: offline_projection
features:
type: object
description: Runtime feature health. Cheap signals only (env + offline counters); no live query in the request path.
required:
- google_signin
- sources_catalog
- data_fresh
properties:
google_signin:
type: string
enum:
- available
- disabled
sources_catalog:
type: string
enum:
- valid
- invalid
data_fresh:
type: boolean
additionalProperties: false
degraded:
type: boolean
description: True when any feature is disabled/invalid or the data is stale (artifacts_age_hours >= 26), even if status is still "ok".
additionalProperties: false
ErrorResponse:
type: object
description: Closed compatibility envelope for public/account errors. Route-specific schemas narrow these fields further where required.
required:
- error
properties:
error:
type: string
minLength: 1
message:
type: string
detail:
type: string
code:
type: string
status:
type:
- integer
- string
projection:
type: string
reason:
type: string
source_catalog_version:
type: string
allowed_parameters:
type: array
uniqueItems: true
items:
type: string
slug:
type: string
key:
type: string
maximum:
type: integer
minimum: 1
parameter:
type: string
fields:
type: array
items:
type: string
max_bytes:
type: integer
minimum: 1
allowed:
type: array
items:
$ref: '#/components/schemas/JsonValue'
valid:
type: array
items:
$ref: '#/components/schemas/JsonValue'
date:
type: string
login_url:
type: string
plan:
type: string
limited_by:
type: string
enum:
- minute
- day
daily_limit:
type: integer
minimum: 1
reset_at:
type: integer
minimum: 1
reset_at_human:
type: string
format: date-time
retry_after_s:
type: integer
minimum: 1
retry_after:
type: integer
minimum: 1
upgrade:
type: string
format: uri
upgrade_url:
type: string
action:
type: string
limit:
type: integer
minimum: 0
remaining:
type: integer
minimum: 0
needed:
type: integer
minimum: 0
shortfall:
type: integer
minimum: 0
ok:
type: boolean
_alias_of:
type: string
additionalProperties: false
JsonValue:
description: A JSON value used only inside explicitly documented extension maps.
oneOf:
- type:
- string
- number
- boolean
- 'null'
- type: array
items:
$ref: '#/components/schemas/JsonValue'
- type: object
additionalProperties:
$ref: '#/components/schemas/JsonValue'
Health:
type: object
properties:
status:
type: string
version:
type: string
companies_indexed:
type: integer
events_indexed:
type: integer
last_updated:
type:
- string
- 'null'
additionalProperties: true
responses:
PublicReadUnavailable:
description: The public read failed closed because its legal source catalog, subject classification, bounded projection, database helper or required artifact is unavailable. Clients must not infer an empty result.
headers:
Cache-Control:
description: Unavailable public reads are never cacheable.
schema:
type: string
const: no-store
Retry-After:
description: Optional number of seconds to wait before retrying.
schema:
type: integer
minimum: 1
content:
application/json:
schema:
anyOf:
- $ref: '#/components/schemas/ProjectionUnavailableError'
- $ref: '#/components/schemas/ErrorResponse'
examples:
legal_layer:
value:
error: legal_layer_unavailable
company_identity:
value:
error: company_public_projection_unavailable
projection:
value:
error: projection_unavailable
detail: La proyección pública requerida no está disponible.
projection: wikidata_company_v1
TooManyRequests:
description: Rate limit exceeded
headers:
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
parameters:
IfNoneMatchHeader:
name: If-None-Match
in: header
required: false
description: Optional RFC 9110 entity-tag validator. Weak validators, comma-separated validator lists and `*` are accepted.
schema:
type: string
minLength: 1
maxLength: 8192
securitySchemes:
cookieAuth:
type: apiKey
in: cookie
name: ob_sess
description: Browser session cookie set after login at /mi-cuenta/login. Mutations also require X-CSRF-Token header (obtain via GET /api/v1/user/me).
apiKey:
type: apiKey
in: header
name: X-API-Key
description: Optional opaque omk_* API credential for public GETs. Anonymous access remains valid; a credential with the operation's x-api-credential-scope (or public:read) selects its account quota. Never place credentials in query strings.
bearerAuth:
type: http
scheme: bearer
bearerFormat: opaque omk_* credential
description: 'Optional Authorization: Bearer transport for the same opaque omk_* API credential accepted by X-API-Key. It is not a JWT or OAuth access token.'
sessionCookie:
type: apiKey
in: cookie
name: session
description: Session cookie issued after web sign-in, required only for billing endpoints.
externalDocs:
description: Documentación narrativa con ejemplos en curl/Python/JavaScript
url: https://openmercantil.es/api/documentacion
x-refined-from:
- openmercantil-openapi-1.9.3.json
- openmercantil-openapi.yml