OpenMercantil Risk Signals API

Documentary risk signals from public sources (AEPD, CNMC, concursos, AEAT moroso, CENDOJ)

Operations 4

GET /api/v1/company/{slug}/sanctions Get policy-gated sanctions dataset #
GET /api/v1/company/{slug}/risk-signals Get documentary risk signals #
GET /api/v1/company/{slug}/aeat-moroso Check policy-gated AEAT debtor-list mention #
GET /api/v1/company/{slug}/embargoes Documentary embargo/garnishment mentions #

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-risk-signals-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-risk-signals-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: OpenMercantil Risk Signals 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: Risk Signals
  description: Documentary risk signals from public sources (AEPD, CNMC, concursos, AEAT moroso, CENDOJ)
paths:
  /api/v1/company/{slug}/sanctions:
    get:
      operationId: getCompanyBySlugSanctions
      tags:
      - Risk Signals
      summary: Get policy-gated sanctions dataset
      description: This route is fail-closed. It returns data only when the exact sanctions dataset has a valid public decision, license metadata and identity policy in the active source catalog. OpenSanctions is currently in review, so the route returns 503 without reading or serializing its payload.
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Sanctions list when the exact dataset is authorized
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CompanySanctionsResponse'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '503':
          $ref: '#/components/responses/LegalLayerUnavailable'
  /api/v1/company/{slug}/risk-signals:
    get:
      operationId: getCompanyBySlugRiskSignals
      tags:
      - Risk Signals
      summary: Get documentary risk signals
      description: Return only documentary signals whose exact dataset and negative-claim surface are authorized by the active source catalog. Other integrated sources are omitted without implying absence of the underlying fact. CENDOJ judgment text, OpenSanctions, AEPD and any unknown dataset are not exposed unless a future version records a field-specific public decision. Appearance never implies guilt, infringement, responsibility or current liability.
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Risk signals with disclaimers
          content:
            application/json:
              schema:
                type: object
                properties:
                  slug:
                    type: string
                  signals_count:
                    type: integer
                  signals:
                    type: array
                    items:
                      type: object
                      properties:
                        type:
                          type: string
                          enum:
                          - aepd_sanction
                          - cnmc_sanction
                          - concurso
                          - aeat_moroso
                          - cendoj_judgment
                          - opensanctions
                          - other
                        source_slug:
                          type: string
                        source_url:
                          type: string
                        date:
                          type: string
                          format: date
                        summary:
                          type: string
                        confidence:
                          type: string
                          enum:
                          - high
                          - medium
                          - low
                        homonymy_warning:
                          type: boolean
                        disclaimer:
                          type: string
                  source_catalog_version:
                    type: string
                  policy_scope:
                    type: string
                  _legal_notice:
                    type: string
                    example: Documentary signals only. Appearance does not imply guilt, infringement or current liability.
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '503':
          $ref: '#/components/responses/PublicReadUnavailable'
  /api/v1/company/{slug}/aeat-moroso:
    get:
      operationId: getCompanyBySlugAeatMoroso
      tags:
      - Risk Signals
      summary: Check policy-gated AEAT debtor-list mention
      description: Negative-claim route gated before lookup. It returns 503 until the exact AEAT dataset has validated reuse, identity-match and cite-or-abstain policy metadata. Appearance would be documentary only and never imply current liability.
      x-rate-limit: free 60/min · 200/day
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Debtor list mention or empty
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CompanyAeatDebtorResponse'
        '404':
          $ref: '#/components/responses/NotFound'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '503':
          $ref: '#/components/responses/LegalLayerUnavailable'
  /api/v1/company/{slug}/embargoes:
    get:
      operationId: getCompanyBySlugEmbargoes
      tags:
      - Risk Signals
      summary: Documentary embargo/garnishment mentions
      description: Return documentary mentions of embargoes (embargo de bienes, anotaciones registrales) when published in public registries. Documentary only — does not certify current status.
      x-rate-limit: free 60/min · 200/day
      parameters:
      - name: slug
        in: path
        required: true
        schema:
          type: string
      responses:
        '200':
          description: Embargo mentions
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CompanyEmbargoesResponse'
        '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
    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'
    NotFound:
      description: Resource not found
      headers:
        Cache-Control:
          $ref: '#/components/headers/NoStoreCacheControl'
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
  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
    DocumentarySanction:
      type: object
      description: Sanitized documentary sanction record; appearance does not imply current liability.
      properties:
        source:
          type:
          - string
          - 'null'
        date:
          type:
          - string
          - 'null'
        authority:
          type:
          - string
          - 'null'
        summary:
          type:
          - string
          - 'null'
        official_url:
          type:
          - string
          - 'null'
          format: uri
        status:
          type:
          - string
          - 'null'
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
    CompanyAeatDebtorResponse:
      type: object
      required:
      - slug
      - listed
      properties:
        slug:
          type: string
        cif:
          type:
          - string
          - 'null'
        listed:
          type: boolean
        debt_eur:
          type:
          - number
          - 'null'
        period:
          type:
          - string
          - 'null'
        published_date:
          type:
          - string
          - 'null'
        history:
          type: array
          items:
            $ref: '#/components/schemas/JsonValue'
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
    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'
    CompanyEmbargoesResponse:
      type: object
      required:
      - slug
      - count
      - items
      - source
      - note
      properties:
        slug:
          type: string
        count:
          type: integer
        summary:
          anyOf:
          - type: object
            properties:
              count:
                type: integer
              total_amount_eur:
                type:
                - number
                - 'null'
              latest_date:
                type:
                - string
                - 'null'
            additionalProperties:
              $ref: '#/components/schemas/JsonValue'
          - type: 'null'
        items:
          type: array
          items:
            $ref: '#/components/schemas/EmbargoRecord'
          maxItems: 100
        source:
          type: string
        note:
          type: string
      additionalProperties: false
    EmbargoRecord:
      type: object
      description: Documentary official-notice record; may not reflect later unpublished resolutions.
      properties:
        date:
          type:
          - string
          - 'null'
        authority:
          type:
          - string
          - 'null'
        summary:
          type:
          - string
          - 'null'
        amount_eur:
          type:
          - number
          - 'null'
        source_url:
          type:
          - string
          - 'null'
          format: uri
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
    CompanySanctionsResponse:
      type: object
      properties:
        slug:
          type: string
        count:
          type: integer
        items:
          type: array
          items:
            $ref: '#/components/schemas/DocumentarySanction'
        source:
          type:
          - string
          - 'null'
        note:
          type:
          - string
          - 'null'
      additionalProperties:
        $ref: '#/components/schemas/JsonValue'
  headers:
    NoStoreCacheControl:
      description: Error responses must not be stored.
      schema:
        type: string
        const: no-store
  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