OpenMercantil Search API
Company and person search endpoints
Company and person search endpoints
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-search-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 Search 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 Search 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: Search
description: Company and person search endpoints
paths:
/api/v1/search:
get:
security:
- {}
- apiKey: []
- bearerAuth: []
x-api-credential-scope: companies:read
operationId: getSearch
x-query-contract:
allowed:
- q
- limit
- offset
unknown: 400 invalid_parameter
non_scalar: 400 invalid_parameter
lexical: 400 invalid_parameter
range: 422 validation_failed
tags:
- Search
summary: Search published Spanish legal entities
description: Corporate-only search over the immutable company_public_v2 projection. It resolves an exact corporate CIF, an exact canonical/safe-alias slug, or a bounded name-prefix pool. DNI/NIE, malformed identifier-shaped input and ambiguous/quarantined CIFs return zero items; there is no raw companies/search_idx or disk-index fallback.
parameters:
- name: q
in: query
required: true
schema:
type: string
minLength: 2
maxLength: 120
example: mercadona
description: 'Search query: company name, alias or CIF.'
- name: limit
in: query
required: false
schema:
type: integer
minimum: 1
maximum: 100
default: 20
description: Maximum number of results.
- name: offset
in: query
required: false
schema:
type: integer
minimum: 0
maximum: 1000
default: 0
description: Bounded pagination offset. Values above 1000 fail with 422; future deep pagination requires a generation-bound cursor.
- $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: Search results
content:
application/json:
schema:
$ref: '#/components/schemas/SearchResponse'
'304':
description: The admitted corporate search projection and exact normalized query have not changed.
'400':
$ref: '#/components/responses/BadRequest'
'422':
$ref: '#/components/responses/ValidationFailed'
'429':
$ref: '#/components/responses/TooManyRequests'
'503':
$ref: '#/components/responses/PublicReadUnavailable'
servers:
- url: https://openmercantil.es
description: Production
/api/v1/person/search:
get:
security:
- {}
- apiKey: []
- bearerAuth: []
x-api-credential-scope: people:read
operationId: getPersonSearch
x-query-contract:
allowed:
- q
- limit
unknown: 400 invalid_parameter
non_scalar: 400 invalid_parameter
lexical: 400 invalid_parameter
range: 422 validation_failed
tags:
- Search
summary: Search documentary mentions of persons
description: Search only person_public_search_v1, bounded to 50 results and revalidated against the activated company_public_v2 generation. Results are unresolved name mentions, never identity profiles. Authority failure is 503/no-store, not an empty result. No raw persons, enrichment or person-procurement fallback.
x-rate-limit: free 60/min · 200/day
parameters:
- name: q
in: query
required: true
schema:
type: string
minLength: 2
maxLength: 200
example: garcia
- name: limit
in: query
required: false
schema:
type: integer
minimum: 1
maximum: 50
default: 20
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'
Cache-Control:
schema:
type: string
const: private, no-store
description: Person search results
content:
application/json:
schema:
$ref: '#/components/schemas/PersonSearchResponse'
'400':
$ref: '#/components/responses/BadRequest'
'422':
$ref: '#/components/responses/ValidationFailed'
'429':
$ref: '#/components/responses/TooManyRequests'
'503':
$ref: '#/components/responses/PublicReadUnavailable'
servers:
- url: https://openmercantil.es
description: Production
components:
responses:
ValidationFailed:
description: The query is lexically valid but outside a documented numeric or length bound, or uses an unsupported indexed combination.
headers:
Cache-Control:
$ref: '#/components/headers/NoStoreCacheControl'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
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'
BadRequest:
description: Invalid request
headers:
Cache-Control:
$ref: '#/components/headers/NoStoreCacheControl'
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse'
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
BadRequest_2:
description: Invalid request
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_2'
TooManyRequests_2:
description: Rate limit exceeded
headers:
Retry-After:
description: Seconds to wait before retrying.
schema:
type: integer
X-RateLimit-Limit:
description: Maximum requests per window (60 per minute by IP on the public anonymous tier).
schema:
type: integer
X-RateLimit-Remaining:
description: Remaining requests in the current window.
schema:
type: integer
X-RateLimit-Reset:
description: Unix timestamp when the rate-limit counter resets.
schema:
type: integer
content:
application/json:
schema:
$ref: '#/components/schemas/ErrorResponse_2'
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
SearchResponse:
type: object
required:
- query
- count
- items
properties:
query:
type: string
count:
type: integer
offset:
type: integer
items:
type: array
items:
$ref: '#/components/schemas/CompanySearchItem'
PersonPublicProjectionMetadata:
type: object
required:
- name
- schema_version
- contract_sha256
- source_generation
- content_sha256
- projected_at
properties:
name:
type: string
const: person_public_v1
schema_version:
type: string
const: '1.0'
contract_sha256:
type: string
pattern: ^[a-f0-9]{64}$
source_generation:
type: string
pattern: ^cpv2-[a-f0-9]{64}$
content_sha256:
type: string
pattern: ^[a-f0-9]{64}$
projected_at:
type: string
format: date-time
additionalProperties: false
SourceCatalogEnvelope:
type: object
required:
- catalog_version
- policy_fingerprint
- sources
properties:
catalog_version:
type: string
policy_fingerprint:
type: string
policy_effective_date:
type: string
format: date
sources:
type: object
additionalProperties:
$ref: '#/components/schemas/PublicSourcePolicyMetadata'
additionalProperties: false
PersonSearchItem:
type: object
description: Documentary person search result; no DNI, contact data or personal address.
required:
- slug
- name
- mentions_count
- companies_count
- first_seen
- last_seen
- subject_type
- identity_resolution
- source_slug
properties:
slug:
type: string
pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$
name:
type: string
minLength: 1
mentions_count:
type: integer
minimum: 1
companies_count:
type: integer
minimum: 1
first_seen:
type:
- string
- 'null'
format: date
last_seen:
type:
- string
- 'null'
format: date
subject_type:
type: string
const: person_documentary_mentions
identity_resolution:
type: string
const: not_performed
source_slug:
type: string
const: borme
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
PersonSearchResponse:
type: object
required:
- schema_version
- status
- query
- count
- items
- subject_type
- identity_resolution
- projection
- _legal_notice
- _source_catalog
- _data_sources_used
properties:
schema_version:
type: string
const: person_search_v1
status:
type: string
const: available
query:
type: string
minLength: 2
maxLength: 200
count:
type: integer
minimum: 0
maximum: 50
items:
type: array
maxItems: 50
items:
$ref: '#/components/schemas/PersonSearchItem'
subject_type:
type: string
const: person_documentary_mentions
identity_resolution:
type: string
const: not_performed
projection:
$ref: '#/components/schemas/PersonPublicProjectionMetadata'
_legal_notice:
type: string
minLength: 1
_source_catalog:
$ref: '#/components/schemas/SourceCatalogEnvelope'
_data_sources_used:
type: array
minItems: 1
items:
$ref: '#/components/schemas/PublicSourcePolicyMetadata'
_attributions:
type: object
additionalProperties:
type: string
additionalProperties: false
PublicSourcePolicyMetadata:
type: object
additionalProperties: false
required:
- slug
- name
- license
- attribution_required
- reuse_conditions
- policy_effective_date
- reviewed_at
- catalog_version
properties:
slug:
type: string
name:
type: string
license:
type: string
license_url:
type:
- string
- 'null'
format: uri
attribution_required:
type: boolean
attribution_text:
type:
- string
- 'null'
official_url:
type:
- string
- 'null'
format: uri
reuse_conditions:
type: string
description: Condiciones de reutilizacion que el consumidor debe conservar al presentar o transformar el dato.
policy_effective_date:
type: string
format: date
reviewed_at:
type: string
format: date
data_updated_at:
type:
- string
- 'null'
format: date-time
catalog_version:
type: string
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'
CompanySearchItem:
type: object
required:
- slug
- name
- cif
- acts_count
properties:
slug:
type: string
example: mercadona-sa
name:
type: string
example: MERCADONA SA
cif:
type: string
example: A46103834
acts_count:
type: integer
last_seen:
type:
- string
- 'null'
province:
type:
- string
- 'null'
cnae_code:
type:
- string
- 'null'
cnae_section:
type:
- string
- 'null'
capital_cents:
type:
- integer
- 'null'
minimum: 0
first_seen:
type:
- string
- 'null'
matched_alias:
type: string
description: Present only when an exact safe alias was matched; slug is always canonical.
aliases:
type: array
items:
type: string
additionalProperties:
$ref: '#/components/schemas/JsonValue'
PersonSearchItem_2:
type: object
properties:
slug:
type: string
name:
type: string
company_count:
type: integer
additionalProperties: true
ErrorResponse_2:
type: object
properties:
error:
type: string
message:
type: string
additionalProperties: true
PersonSearchResponse_2:
type: object
properties:
query:
type: string
count:
type: integer
items:
type: array
items:
$ref: '#/components/schemas/PersonSearchItem_2'
additionalProperties: true
CompanySearchItem_2:
type: object
properties:
slug:
type: string
example: mercadona-sa
name:
type: string
example: MERCADONA SA
cif:
type: string
example: A46103834
acts_count:
type: integer
last_seen:
type:
- string
- 'null'
aliases:
type: array
items:
type: string
additionalProperties: true
headers:
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
NoStoreCacheControl:
description: Error responses must not be stored.
schema:
type: string
const: no-store
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
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
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