OpenMercantil Persons API

Documentary mentions of natural persons in BORME (officer roles). Persons treated as documentary mentions only — no DNI, no contact data, no scoring.

Operations 5

GET /api/v1/company/{slug}/officers Get current and historical company officers #
GET /api/v1/persona/{slug} Get documentary mentions of a person #
GET /api/v1/person/{slug} Get documentary person mentions through the legacy English alias #
GET /api/v1/person/search Search documentary mentions of persons #
GET /api/v1/persona/{slug}/contracts Person-to-procurement derivation (unavailable) #

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.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/openmercantil-persons-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no email required.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

openmercantil-persons-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Openmercantil Persons 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 Persons 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: Persons
  description: Documentary mentions of natural persons in BORME (officer roles). Persons treated as documentary mentions only — no DNI, no contact data, no scoring.
paths:
  /api/v1/company/{slug}/officers:
    get:
      security:
      - {}
      - apiKey: []
      - bearerAuth: []
      x-api-credential-scope: companies:read
      operationId: getCompanyBySlugOfficers
      tags:
      - Persons
      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/persona/{slug}:
    get:
      security:
      - {}
      - apiKey: []
      - bearerAuth: []
      x-api-credential-scope: people:read
      operationId: getPersonaBySlug
      tags:
      - Persons
      summary: Get documentary mentions of a person
      description: Return an exact, attested person_public_v1 documentary-mention report bound to the same company_public_v2 source generation. Available is 200/private no-store; absent, withheld, ambiguous or quarantined is a neutral 404; authority, hash, binding or generation failure is 503/no-store. No raw persons fallback. No DNI/NIE, contact/address, photo/social data, enrichment, sanctions, scoring, person-procurement inference, identity resolution or vigency inference.
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          example: calero-brazalez-juan-jose
      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
              description: no-store
          description: Person documentary mentions
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PersonDocumentaryReport'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '503':
          $ref: '#/components/responses/PublicReadUnavailable'
    servers:
    - url: https://openmercantil.es
      description: Production
  /api/v1/person/{slug}:
    get:
      operationId: getLegacyPersonBySlug
      tags:
      - Persons
      summary: Get documentary person mentions through the legacy English alias
      description: Deprecated alias of `GET /api/v1/persona/{slug}`. The response remains a neutral set of attributed BORME documentary mentions, never an identity profile.
      deprecated: true
      x-replaced-by: /api/v1/persona/{slug}
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          example: calero-brazalez-juan-jose
      responses:
        '200':
          description: Same closed person_public_v1 report as the canonical Spanish route
          headers:
            Content-Location:
              schema:
                type: string
              description: Canonical /api/v1/persona/{slug} path
            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
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PersonDocumentaryReport'
        '404':
          $ref: '#/components/responses/NotFound'
        '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:
      - Persons
      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
  /api/v1/persona/{slug}/contracts:
    get:
      operationId: getPersonaBySlugContracts
      tags:
      - Persons
      summary: Person-to-procurement derivation (unavailable)
      description: Fail-closed derived route. It always returns 503 before reading data because `person_contracts_v1` is not authorized. A future implementation requires a new reviewed projection and contract version.
      deprecated: true
      x-rate-limit: plan policy (see info.x-rate-limit)
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
      responses:
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '503':
          $ref: '#/components/responses/LegalLayerUnavailable'
    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'
    LegalLayerUnavailable:
      description: 'Controlled fail-closed denial: the required dataset or legal layer is absent, invalid, unsupported or not authorized for this public surface.'
      headers:
        Cache-Control:
          $ref: '#/components/headers/NoStoreCacheControl'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error: legal_layer_unavailable
            detail: Este dataset no esta habilitado para redistribucion publica por la politica de fuentes activa.
            source_catalog_version: 2026-07-12.2
    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'
    NotFound:
      description: Resource not found
      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'
    NotFound_2:
      description: Resource not found
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse_2'
  schemas:
    PersonDocumentaryReport:
      type: object
      description: Exact person_public_v1 report. It groups unresolved BORME name mentions and never proves identity or current vigency.
      required:
      - slug
      - name
      - first_seen
      - last_seen
      - companies_count
      - active_positions
      - inactive_positions
      - subject_type
      - identity_resolution
      - positions_semantics
      - _legal_notice
      - _correction_channel
      - schema_version
      - status
      - projection
      - _source_catalog
      - _data_sources_used
      properties:
        slug:
          type: string
          pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$
        name:
          type: string
          minLength: 1
        first_seen:
          type:
          - string
          - 'null'
          format: date
        last_seen:
          type:
          - string
          - 'null'
          format: date
        companies_count:
          type: integer
          minimum: 1
        active_positions:
          type: array
          items:
            $ref: '#/components/schemas/PersonDocumentaryPosition'
        inactive_positions:
          type: array
          items:
            $ref: '#/components/schemas/PersonDocumentaryPosition'
        subject_type:
          type: string
          const: person_documentary_mentions
        identity_resolution:
          type: string
          const: not_performed
        positions_semantics:
          type: string
          minLength: 1
        _legal_notice:
          type: string
          minLength: 1
        _correction_channel:
          type: string
          format: uri
          const: https://openmercantil.es/proteccion-de-datos/derechos
        schema_version:
          type: string
          const: person_documentary_report_v1
        status:
          type: string
          const: available
        projection:
          $ref: '#/components/schemas/PersonPublicProjectionMetadata'
        _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
    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
    OfficerDocumentaryMention:
      type: object
      description: Documentary officer mention. It never contains DNI, contact details or a personal address.
      properties:
        name:
          type: string
        person_slug:
          type:
          - string
          - 'null'
        role:
          type:
          - string
          - 'null'
        appointed_at:
          type:
          - string
          - 'null'
        ended_at:
          type:
          - string
          - 'null'
        source:
          type:
          - string
          - 'null'
        source_url:
          type:
          - string
          - 'null'
          format: uri
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
    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
    OfflineProjectionError:
      type: object
      required:
      - error
      properties:
        error:
          type: string
        projection:
          type:
          - string
          - 'null'
        derivation:
          type:
          - string
          - 'null'
        detail:
          type:
          - string
          - 'null'
      additionalProperties: false
    PersonDocumentaryPosition:
      type: object
      required:
      - company
      - company_name
      - company_slug
      - cif
      - role
      - since
      - until
      - documentary_status
      - vigency_verified
      - source_slug
      - source_url
      properties:
        company:
          type: string
          minLength: 1
        company_name:
          type: string
          minLength: 1
        company_slug:
          type: string
          pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$
        cif:
          type: string
          description: Admitted legal-entity CIF; never a natural-person identifier.
        role:
          type:
          - string
          - 'null'
        since:
          type:
          - string
          - 'null'
          format: date
        until:
          type:
          - string
          - 'null'
          format: date
        documentary_status:
          type: string
          enum:
          - open_documentary_mention
          - historical_documentary_mention
        vigency_verified:
          type: boolean
          const: false
        source_slug:
          type: string
          const: borme
        source_url:
          type: string
          format: uri
          const: https://www.boe.es/diario_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
    OfficerList:
      type: array
      maxItems: 500
      items:
        $ref: '#/components/schemas/OfficerDocumentaryMention'
    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'
    Officer:
      type: object
      properties:
        person_slug:
          type: string
        name:
          type: string
        role:
          type: string
        appointed:
          type:
          - string
          - 'null'
          format: date
        ceased:
          type:
          - string
          - 'null'
          format: date
      additionalProperties: true
    PersonSearchItem_2:
      type: object
      properties:
        slug:
          type: string
        name:
          type: string
        company_count:
          type: integer
      additionalProperties: true
    PersonReport:
      type: object
      properties:
        slug:
          type: string
        name:
          type: string
        roles:
          type: array
          items:
            $ref: '#/components/schemas/Officer'
      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
  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
  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