OpenMercantil Integrations API

Public read-only connector catalog. Never exposes credentials, OAuth tokens, webhook secrets or operator actions.

Operations 3

POST /api/v1/stripe-webhook Receive a signed Stripe event #
GET /api/v1/integrations List public integration capabilities #
GET /api/v1/integrations/{slug} Get one public integration contract #

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-integrations-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-integrations-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: OpenMercantil Integrations API
  version: 1.9.3
  summary: Versioned public-read, browser-account, billing, support and provider-callback contracts.
  description: 'Public JSON API for Spanish company information derived from BORME and other public sources. OpenMercantil is an independent informational service; it is NOT the BOE, BORME or Registro Mercantil and does NOT replace official certificates or registry extracts.


    **Rate limits.** Free: 60 req/min y 200 req/día por IP. Planes superiores (Profesional 5.000 req/día, MAX 50.000 req/día, Enterprise 500.000+ req/día) según cuenta y API key. Cabeceras `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset`, `X-OpenMercantil-Plan`, `Retry-After`.


    **License and attribution.** Source-specific metadata in each response and the active versioned source catalog prevails. OpenMercantil does not relicense upstream content under a blanket license. Unknown, review and restricted datasets are omitted or return `503 legal_layer_unavailable`. BOE/BORME material is re-used under Ley 37/2007 and its official version remains boe.es. Court judgments are not exposed; CENDOJ remains citation-index only under CGPJ Reglamento 3/2010.


    **Machine-readable catalog (DCAT-AP-ES):** https://openmercantil.es/catalog.rdf'
  termsOfService: https://openmercantil.es/terminos-de-uso
  contact:
    name: OpenMercantil
    url: https://openmercantil.es/soporte
    email: social@openmercantil.es
  license:
    name: Source-specific upstream terms; see response catalog metadata
    url: https://openmercantil.es/terminos-de-uso
  x-publisher:
    name: OpenMercantil
    url: https://openmercantil.es/
    email: social@openmercantil.es
  x-spatial: http://publications.europa.eu/resource/authority/country/ESP
  x-temporal: 2009-01-01/..
  x-language: es
  x-dcat-catalog: https://openmercantil.es/catalog.rdf
  x-rate-limit:
    free:
      per_min: 60
      per_day: 200
      kind: anonymous-ip
    profesional:
      per_min: 120
      per_day: 5000
      kind: api-key
    max:
      per_min: 600
      per_day: 50000
      kind: api-key
    enterprise:
      per_min: 1200
      per_day: 500000
      kind: contract
  x-methodology: https://openmercantil.es/metodologia
  x-sources: https://openmercantil.es/fuentes
  x-corrections: https://openmercantil.es/correcciones
  x-contract-status: Public read, browser-account and provider-callback surfaces are explicitly separated in this contract. Operator/admin routes are excluded. The public MCP consumes only the allowlisted GET read plane.
  x-account-segment-contract:
    projection: company_public_v2 immutable corporate sidecar
    synchronous_row_cap: 500
    bounded_count_cap: 50001
    count_semantics: The segment run response count is the number of rows returned, never a global total. Dataset preview uses total_is_lower_bound=true and total_lower_bound when the bounded count reaches 50001.
    related_web_dataset_surface:
      preview_path: /mi-cuenta/datasets/preview
      export_path: /mi-cuenta/datasets/export.csv
      synchronous_export_max_rows: 500
      overflow_status: 503
      overflow_error: async_export_required
  x-company-identity-contract:
    version: '1.0'
    projection: company_public_v2 immutable generation-bound corporate sidecar
    applies_to: Every /api/v1/company/{slug}*, /api/v1/empresa/{slug}* and /api/v1/grafo/{slug} read before any report, cache, graph or dataset lookup. /api/v1/companies/compare resolves both requested subjects in one bounded company_public_v2 batch before either row is exposed; MCP company tools inherit these preflights through REST.
    resolution:
      published: canonical corporate slug admitted
      safe_alias: internally canonicalized and Content-Location emitted
      withheld: neutral 404; includes absent, personal and ambiguous/quarantined identities
      unavailable: 503 with no-store; clients must not infer absence
    search: Exact corporate CIF, exact canonical/safe-alias slug, or bounded name_prefix2 pool scored in application code. DNI/NIE and ambiguous CIFs return zero items.
    public_company_count: company_public_projection_state.row_count
servers:
- url: https://openmercantil.es
  description: Production
tags:
- name: Integrations
  description: Public read-only connector catalog. Never exposes credentials, OAuth tokens, webhook secrets or operator actions.
paths:
  /api/v1/stripe-webhook:
    post:
      operationId: receiveStripeWebhook
      tags:
      - Integrations
      summary: Receive a signed Stripe event
      description: Provider callback, not an end-user API. The exact raw JSON body is capped at 512 KiB and verified against `Stripe-Signature` before durable inbox claim or side effects. Provider `event.id` supplies idempotency; terminal duplicates return 200, active leases return 503 for retry, and failures return 500 so Stripe retries. No webhook secret, signature, raw payload or internal exception is returned. This route is excluded from every public MCP surface.
      x-plane: integration-provider-callback
      x-provider: stripe
      x-max-body-bytes: 524288
      x-idempotency-key: Stripe event.id
      x-log-policy: Redact Stripe-Signature and the raw request body
      x-mcp-excluded: true
      security: []
      parameters:
      - name: Stripe-Signature
        in: header
        required: true
        description: Stripe-generated signature verified over the exact raw body. It is sensitive request metadata and must never be logged or echoed.
        schema:
          type: string
          minLength: 1
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StripeWebhookEventRequest'
      responses:
        '200':
          description: Event accepted, deliberately ignored, or already terminal. All response bodies are non-secret acknowledgements.
          content:
            text/plain:
              schema:
                type: string
                enum:
                - ok
                - duplicate (terminal idempotent skip)
                - ignored (other source)
                - credits ok
                - donation ok
                - subscription missing
                - historical subscription ignored
                - clawback rejected
                - clawback
                - ignored
                - ignored invoice
                - ignored payment failure
        '400':
          description: Signature missing/invalid, or the raw request stream cannot be read
          content:
            text/plain:
              schema:
                type: string
                const: Bad signature
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error: request_body_unreadable
        '413':
          description: Raw callback body exceeds 512 KiB
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RequestBodyTooLargeError'
              example:
                error: request_body_too_large
                max_bytes: 524288
        '500':
          description: Inbox persistence or event processing failed; Stripe must retry
          content:
            text/plain:
              schema:
                type: string
                enum:
                - webhook inbox unavailable
                - error
        '503':
          description: Another worker owns an active lease or a signed OpenMercantil checkout cannot yet be resolved to its authoritative account owner; Stripe must retry
          headers:
            Retry-After:
              description: Retry delay in seconds
              schema:
                type: integer
                const: 5
          content:
            text/plain:
              schema:
                type: string
                enum:
                - event already processing
                - credits owner unavailable
                - subscription owner unavailable
  /api/v1/integrations:
    get:
      security:
      - {}
      - apiKey: []
      - bearerAuth: []
      x-api-credential-scope: integrations:read
      operationId: listIntegrations
      tags:
      - Integrations
      summary: List public integration capabilities
      description: 'Versioned fail-closed catalog that reports legal egress permission separately from technical transport availability. public_read is false when permission exists but no safe projection is active; separate_authority delegates validation to the endpoint''s own fail-closed contract. Sources in review, restricted or unknown are omitted. The query contract is closed: capability is optional, but when present it must match the documented lowercase pattern byte-for-byte; empty, padded or upper-case values and unknown parameters return 400. Provenance contains exactly the sources represented by the returned items. This is not an operator health probe and never includes credentials, OAuth tokens, webhook secrets, billing or internal errors.'
      parameters:
      - name: capability
        in: query
        schema:
          type: string
          pattern: ^[a-z][a-z0-9_-]{1,40}$
      - $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'
            ETag:
              $ref: '#/components/headers/EntityTag'
            Cache-Control:
              $ref: '#/components/headers/PrivateRevalidationCacheControl'
          description: Public integration catalog
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IntegrationListResponse'
        '304':
          description: The legal catalog and technical transport snapshot 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'
            ETag:
              $ref: '#/components/headers/EntityTag'
            Cache-Control:
              $ref: '#/components/headers/PrivateRevalidationCacheControl'
        '400':
          $ref: '#/components/responses/BadRequest'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '503':
          $ref: '#/components/responses/LegalLayerUnavailable'
  /api/v1/integrations/{slug}:
    get:
      security:
      - {}
      - apiKey: []
      - bearerAuth: []
      x-api-credential-scope: integrations:read
      operationId: getIntegration
      tags:
      - Integrations
      summary: Get one public integration contract
      description: Return the legal-egress decision and the independent technical transport status for one catalogued integration. This detail route accepts no query parameters; unknown parameters return 400.
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
          pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$
      - $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'
            ETag:
              $ref: '#/components/headers/EntityTag'
            Cache-Control:
              $ref: '#/components/headers/PrivateRevalidationCacheControl'
          description: Public integration metadata
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/IntegrationDetailResponse'
        '304':
          description: The legal decision and technical transport snapshot 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'
            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/LegalLayerUnavailable'
components:
  responses:
    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'
  headers:
    EntityTag:
      description: Strong generation-bound entity tag for conditional GET.
      schema:
        type: string
        pattern: ^"[a-f0-9]{64}"$
    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
    PrivateRevalidationCacheControl:
      description: Caller-specific rate-limit and plan headers make this representation private. A private cache may retain the body but must revalidate every request; shared caches must not store or reuse it.
      schema:
        type: string
        const: private, no-cache, must-revalidate
    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
  schemas:
    PublicIntegrationTransport:
      type: object
      description: Technical read-plane status. unavailable has no endpoint; separate_authority delegates fail-closed validation to the listed endpoint contract and is not a health probe.
      required:
      - status
      - projection
      - generation
      - endpoints
      properties:
        status:
          type: string
          enum:
          - available
          - unavailable
          - separate_authority
        projection:
          type:
          - string
          - 'null'
        generation:
          type:
          - string
          - 'null'
        endpoints:
          type: array
          maxItems: 8
          items:
            type: string
            pattern: ^/api/v1/
      oneOf:
      - properties:
          status:
            const: available
          projection:
            type: string
            minLength: 1
          generation:
            type: string
            pattern: ^(?:cipv1|sr1)-[a-f0-9]{64}$
          endpoints:
            minItems: 1
      - properties:
          status:
            const: unavailable
          generation:
            type: 'null'
          endpoints:
            maxItems: 0
      - properties:
          status:
            const: separate_authority
          projection:
            type: string
            minLength: 1
          generation:
            type: 'null'
          endpoints:
            minItems: 1
      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
    PublicIntegrationCoverage:
      type: object
      properties:
        multi_lot:
          type:
          - string
          - 'null'
        multiple_cpv:
          type:
          - string
          - 'null'
        geography:
          type:
          - string
          - 'null'
      additionalProperties: false
    PublicIntegrationContract:
      type: object
      required:
      - surface
      - secrets_exposed
      - writes_exposed
      properties:
        surface:
          type: string
          const: public-read-only
        secrets_exposed:
          type: boolean
          const: false
        writes_exposed:
          type: boolean
          const: false
        health_semantics:
          type:
          - string
          - 'null'
        excluded:
          type: array
          items:
            type: string
      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
    IntegrationListResponse:
      type: object
      required:
      - schema_version
      - source_catalog_version
      - count
      - items
      - contract
      - _source_catalog
      - _data_sources_used
      properties:
        schema_version:
          type: string
        source_catalog_version:
          type: string
        count:
          type: integer
        items:
          type: array
          items:
            $ref: '#/components/schemas/PublicIntegration'
        contract:
          $ref: '#/components/schemas/PublicIntegrationContract'
        _source_catalog:
          $ref: '#/components/schemas/SourceCatalogEnvelope'
        _data_sources_used:
          type: array
          items:
            $ref: '#/components/schemas/PublicSourcePolicyMetadata'
        _attributions:
          type: object
          additionalProperties:
            type: string
      additionalProperties: false
    StripeWebhookEventRequest:
      type: object
      description: Stripe Event envelope. The exact signed raw bytes, not a reserialized object, are used for verification. Provider extension fields remain typed JSON and are not reflected to callers.
      required:
      - id
      - type
      - data
      properties:
        id:
          type: string
          minLength: 1
          description: Provider event id and durable idempotency key.
        object:
          type: string
          const: event
        type:
          type: string
          minLength: 1
        created:
          type: integer
          minimum: 0
        livemode:
          type: boolean
        api_version:
          type:
          - string
          - 'null'
        data:
          type: object
          required:
          - object
          properties:
            object:
              type: object
              additionalProperties:
                $ref: '#/components/schemas/JsonValue'
            previous_attributes:
              type: object
              additionalProperties:
                $ref: '#/components/schemas/JsonValue'
          additionalProperties:
            $ref: '#/components/schemas/JsonValue'
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
    PublicIntegrationEgressPolicy:
      type: object
      description: Legal permission from the active source catalog. It does not claim that a technical projection is deployed.
      required:
      - status
      - catalog_version
      - policy_effective_date
      - reviewed_at
      properties:
        status:
          type: string
          const: allowed
        catalog_version:
          type: string
          minLength: 1
        policy_effective_date:
          type: string
          format: date
        reviewed_at:
          type: string
          format: date
      additionalProperties: false
    PublicIntegration:
      type: object
      required:
      - slug
      - source_slug
      - name
      - kind
      - capabilities
      - public_read
      - egress_policy
      - transport
      - official_url
      - license
      - attribution_required
      - reuse_conditions
      - policy_effective_date
      - reviewed_at
      - catalog_version
      properties:
        slug:
          type: string
          pattern: ^[a-z0-9]+(?:-[a-z0-9]+)*$
        source_slug:
          type: string
          description: Canonical source slug from the active public-source catalog.
        name:
          type: string
        kind:
          type: string
        capabilities:
          type: array
          items:
            type: string
        public_read:
          type: boolean
          description: True only when transport.status is available or separate_authority; never derived from legal permission alone.
        egress_policy:
          $ref: '#/components/schemas/PublicIntegrationEgressPolicy'
        transport:
          $ref: '#/components/schemas/PublicIntegrationTransport'
        official_url:
          type: string
          format: uri
        license:
          type: string
        license_url:
          type:
          - string
          - 'null'
          format: uri
        attribution_required:
          type: boolean
        attribution_text:
          type:
          - string
          - 'null'
        reuse_conditions:
          type: string
          description: Condiciones de reutilizacion aplicables a esta integracion publica.
        policy_effective_date:
          type: string
          format: date
        reviewed_at:
          type: string
          format: date
        catalog_version:
          type: string
        coverage:
          $ref: '#/components/schemas/PublicIntegrationCoverage'
      additionalProperties: false
    RequestBodyTooLargeError:
      type: object
      required:
      - error
      - max_bytes
      properties:
        error:
          type: string
          const: request_body_too_large
        max_bytes:
          type: integer
          minimum: 1
      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'
    IntegrationDetailResponse:
      type: object
      required:
      - schema_version
      - source_catalog_version
      - integration
      - contract
      - _source_catalog
      - _data_sources_used
      properties:
        schema_version:
          type: string
        source_catalog_version:
          type: string
        integration:
          $ref: '#/components/schemas/PublicIntegration'
        contract:
          $ref: '#/components/schemas/PublicIntegrationContract'
        _source_catalog:
          $ref: '#/components/schemas/SourceCatalogEnvelope'
        _data_sources_used:
          type: array
          items:
            $ref: '#/components/schemas/PublicSourcePolicyMetadata'
        _attributions:
          type: object
          additionalProperties:
            type: string
      additionalProperties: false
  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.'
externalDocs:
  description: Documentación narrativa con ejemplos en curl/Python/JavaScript
  url: https://openmercantil.es/api/documentacion