OpenMercantil System API

Service health and metadata

Operations 2

Each operation below carries the questions people ask an LLM about it and the instructions they give an agent to run it. Generated by API Evangelist overlay

GET /api/v1/health Check service health and BORME freshness · Service health #
Ask an LLM
“Is the OpenMercantil service up right now?”
“How fresh is the BORME data the service is serving?”
Tell an agent
Check the service health.
Tell me whether the API is healthy and when BORME was last loaded.
GET /api/v1/stats Get counts of published companies · Published public-dataset counters #
Ask an LLM
“How many Spanish legal entities are published in the dataset?”
“Is there an approximate count of person mentions as well as companies?”
Tell an agent
Get the published dataset counters.
Report how many companies are currently published.

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:openmercantil-system-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 form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

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

OpenAPI Specification

openmercantil-system-api-openapi.yml Raw ↑
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:
  schemas:
    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'
    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
    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
    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'
  headers:
    StatsGeneration:
      description: Exact shared generation of the active CCAA, sector, sources and global-counters bundle.
      schema:
        type: string
        pattern: ^asv1-[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
    EntityTag:
      description: Strong generation-bound entity tag for conditional GET.
      schema:
        type: string
        pattern: ^"[a-f0-9]{64}"$
  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