Government — entry 086 of 90

OpenMercantil

Verified Jul 2026

OpenMercantil is a REST API over Spain's BORME (Boletín Oficial del Registro Mercantil) company registry, aggregating roughly 2.8 million companies, 970,000 officers, and 7.1 million corporate acts from 29 official sources. Core endpoints, confirmed live, cover company and person search, per-company event timelines, and daily BORME summaries in JSON or CSV, plus premium add-ons like trust scores, ownership networks, and sanctions screening. The free tier needs no API key and has open CORS, capped at 60 requests/minute and 200/day; paid Profesional/MAX/Enterprise tiers raise those limits via an API key.

spainbusiness-registrycompany-databormeopen-data
AuthenticationNone requiredCall it straight away — no key, no signup.
HTTPSSupportedTraffic is encrypted in transit.
CORSEnabledCallable directly from browser JavaScript.
PricingFreemiumA usable free tier exists, with paid plans for more volume.
FormatsJSON, CSVResponses can be requested as JSON or CSV.

GreatAPIs Score

Score97out of 100
Authentication25/25No authentication required
Pricing17/20Freemium tier available
Docs20/20Machine-readable spec file bundled
Formats15/15Supports 2 response formats
Freshness20/20Verified within 6 months

Embed this badge

Scored 97 on greatapis.com
<a href="https://greatapis.com/api/openmercantil/"><img src="https://greatapis.com/badge/openmercantil.svg" alt="Scored 97 on greatapis.com"></a>

Auth quickstart

  1. No key needed — call it now.
Stored keyNo key stored

Your key is stored only in this browser (localStorage) and sent directly to the API — never to greatapis.

Endpoints

Servers
https://openmercantil.es
Auth
apiKeybearerAuthcookieAuth
Search1

Company and person search endpoints

GET/api/v1/searchSearch published Spanish legal entities
Parameters
NameInRequiredType
qqueryyesstring
limitquerynointeger
offsetquerynointeger
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200Search resultsSearchResponse
304The admitted corporate search projection and exact normalized query have not changed.—
400——
422——
429——
503——
Companies30

Company reports and registry events

GET/api/v1/companies/compareCompare exactly two admitted companies
Parameters
NameInRequiredType
slugsqueryyesarray
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200Two admitted companies in stable canonical orderCompanyCompareResponse
304The generation-bound comparison has not changed—
400Malformed pair or both inputs resolve to the same companyCompanyCompareInvalidRequest
404At least one subject is absent, personal, ambiguous, quarantined or legally withheldCompanyCompareNotFound
429——
503The immutable company comparison projection or its authority is unavailable—
GET/api/v1/company/{slug}Get a company report
Parameters
NameInRequiredType
slugpathyesstring
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200Company reportCompanyReport
304The admitted, attested company report has not changed.—
404——
429——
503——
GET/api/v1/company/{slug}/accountsGet policy-gated filed accounts metadata
Parameters
NameInRequiredType
slugpathyesstring
Responses
StatusDescriptionSchema
200Accounts metadata listCompanyAccountsResponse
404——
429——
503——
GET/api/v1/company/{slug}/activityActivity time series
Parameters
NameInRequiredType
slugpathyesstring
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200Time seriesCompanyActivityResponse
304The admitted activity projection has not changed.—
404——
429——
503Source policy, subject classification or activity projection unavailableErrorResponse
GET/api/v1/company/{slug}/aeat-morosoCheck policy-gated AEAT debtor-list mention
Parameters
NameInRequiredType
slugpathyesstring
Responses
StatusDescriptionSchema
200Debtor list mention or emptyCompanyAeatDebtorResponse
404——
429——
503——
GET/api/v1/company/{slug}/bdeGet Banco de España sector ratios for a company CNAE
Parameters
NameInRequiredType
slugpathyesstring
Responses
StatusDescriptionSchema
200CNAE sector-ratio projection or its documented empty shapeCompanyBdeResponse
404——
429——
503——
GET/api/v1/company/{slug}/cnmvGet the CNMV listed-company projection and recent events
Parameters
NameInRequiredType
slugpathyesstring
limitquerynointeger
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200CNMV listed-company projection or its documented empty shapeCompanyCnmvResponse
304The admitted company, projection generation and legal envelope have not changed—
400——
404——
422——
429——
503——
GET/api/v1/company/{slug}/contractsGet PLACSP procurement notices linked to a legal entity
Parameters
NameInRequiredType
slugpathyesstring
limitquerynointeger
Responses
StatusDescriptionSchema
200Contracts listCompanyProcurementResponse
400——
404——
422——
429——
500——
503——
GET/api/v1/company/{slug}/embargoesDocumentary embargo/garnishment mentions
Parameters
NameInRequiredType
slugpathyesstring
Responses
StatusDescriptionSchema
200Embargo mentionsCompanyEmbargoesResponse
404——
429——
503——
GET/api/v1/company/{slug}/enrichmentFail-closed public enrichment payload
Parameters
NameInRequiredType
slugpathyesstring
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200Enrichment payloadCompanyEnrichmentResponse
304The admitted enrichment projection and source policy have not changed.—
404——
429——
503——
GET/api/v1/company/{slug}/eventsGet paginated company events
Parameters
NameInRequiredType
slugpathyesstring
yearquerynointeger
pagequerynointeger
page_sizequerynointeger
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200Paginated event listCompanyEventsResponse
304The generation-bound event page has not changed.—
400——
404——
422A validly typed year, page or page_size is outside its documented rangeErrorResponse
429——
500——
503——
GET/api/v1/company/{slug}/exportExport a single company report
Parameters
NameInRequiredType
slugpathyesstring
Responses
StatusDescriptionSchema
200ExportCompanyReport
400——
404——
429——
503Bounded cached company projection unavailableOfflineProjectionError
GET/api/v1/company/{slug}/factsGet extracted BORME facts through the legacy English alias
Parameters
NameInRequiredType
slugpathyesstring
limitquerynointeger
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200Grouped factsCompanyFactsResponse
304The attested facts report and exact limit have not changed.—
400——
404——
422——
429——
500——
503——
GET/api/v1/company/{slug}/geocodeCompany geocode projection (unavailable)
Parameters
NameInRequiredType
slugpathyesstring
Responses
StatusDescriptionSchema
404——
429——
503——
GET/api/v1/company/{slug}/grantsGet BDNS public grants
Parameters
NameInRequiredType
slugpathyesstring
limitquerynointeger
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200Grants listCompanyGrantsResponse
304The admitted company, projection generation and legal envelope have not changed—
400——
404——
422——
429——
503——
GET/api/v1/company/{slug}/ipGet policy-gated aggregated trademarks and patents
Parameters
NameInRequiredType
slugpathyesstring
Responses
StatusDescriptionSchema
200Trademarks + patents counts with states legend—
404——
429——
503——
GET/api/v1/company/{slug}/leiGet policy-gated GLEIF LEI record
Parameters
NameInRequiredType
slugpathyesstring
Responses
StatusDescriptionSchema
200LEI record when GLEIF is authorizedCompanyLeiResponse
404——
429——
503——
GET/api/v1/company/{slug}/networkDocumentary network projection (temporarily unavailable)
Parameters
NameInRequiredType
slugpathyesstring
Responses
StatusDescriptionSchema
404——
429——
503Offline projection requiredOfflineProjectionError
GET/api/v1/company/{slug}/officersGet current and historical company officers
Parameters
NameInRequiredType
slugpathyesstring
Responses
StatusDescriptionSchema
200Officer listOfficerList
404——
429——
503Bounded cached officer projection unavailableOfflineProjectionError
GET/api/v1/company/{slug}/procurementAlias of /contracts
Parameters
NameInRequiredType
slugpathyesstring
Responses
StatusDescriptionSchema
200Procurement awards (alias of contracts)CompanyProcurementResponse
400——
404——
429——
500——
503Legal-first PLACSP projection unavailable—
GET/api/v1/company/{slug}/relationshipsGet documentary relationships of a company
Parameters
NameInRequiredType
slugpathyesstring
typequerynostring
confidencequerynostring
Responses
StatusDescriptionSchema
200Documented relationships listCompanyRelationshipsResponse
400——
404——
429——
500——
503——
GET/api/v1/company/{slug}/risk-signalsGet documentary risk signals
Parameters
NameInRequiredType
slugpathyesstring
Responses
StatusDescriptionSchema
200Risk signals with disclaimers—
404——
429——
503——
GET/api/v1/company/{slug}/sanctionsGet policy-gated sanctions dataset
Parameters
NameInRequiredType
slugpathyesstring
Responses
StatusDescriptionSchema
200Sanctions list when the exact dataset is authorizedCompanySanctionsResponse
404——
429——
503——
GET/api/v1/company/{slug}/scoreDocumentary completeness score (no risk/credit scoring)
Parameters
NameInRequiredType
slugpathyesstring
Responses
StatusDescriptionSchema
200Completeness scoreCompanyActivityScoreResponse
404——
429——
503——
GET/api/v1/company/{slug}/similarSimilar companies (province + CNAE2 + BORME activity)
Parameters
NameInRequiredType
slugpathyesstring
limitquerynointeger
Responses
StatusDescriptionSchema
200Similar companies listCompanySimilarResponse
400——
404——
422——
429——
503——
GET/api/v1/company/{slug}/sourcesGet bounded public integration coverage for a company
Parameters
NameInRequiredType
slugpathyesstring
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200Generation-bound coverage for exactly four safe company integrationsCompanySourcesResponse
304The admitted company, projection generation and legal envelope have not changed—
400——
404——
429——
503——
GET/api/v1/company/{slug}/tedGet TED notice records linked to this corporate NIF
Parameters
NameInRequiredType
slugpathyesstring
limitquerynointeger
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200Bounded TED documentary records linked to the admitted corporate NIFCompanyTedResponse
304The admitted company, projection generation and legal envelope have not changed—
400——
404——
422——
429——
503——
GET/api/v1/company/{slug}/timelineGet unified multi-source company timeline
Parameters
NameInRequiredType
slugpathyesstring
Responses
StatusDescriptionSchema
200Multi-source timeline—
404——
429——
503——
GET/api/v1/company/{slug}/wikidataGet the bounded Wikidata company metadata projection
Parameters
NameInRequiredType
slugpathyesstring
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200Wikidata metadata projection or its documented empty shapeCompanyWikidataResponse
304The admitted company, projection generation and legal envelope have not changed—
400——
404——
429——
503——
GET/api/v1/empresa/{slug}/factsGet extracted BORME facts for a company
Parameters
NameInRequiredType
slugpathyesstring
limitquerynointeger
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200Grouped factsCompanyFactsResponse
304The attested facts report and exact limit have not changed.—
400——
404——
422——
429——
500——
503——
Persons4

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

GET/api/v1/person/searchSearch documentary mentions of persons
Parameters
NameInRequiredType
qqueryyesstring
limitquerynointeger
Responses
StatusDescriptionSchema
200Person search resultsPersonSearchResponse
400——
422——
429——
503——
GET/api/v1/person/{slug}Get documentary person mentions through the legacy English alias
Parameters
NameInRequiredType
slugpathyesstring
Responses
StatusDescriptionSchema
200Same closed person_public_v1 report as the canonical Spanish routePersonDocumentaryReport
404——
429——
503——
GET/api/v1/persona/{slug}Get documentary mentions of a person
Parameters
NameInRequiredType
slugpathyesstring
Responses
StatusDescriptionSchema
200Person documentary mentionsPersonDocumentaryReport
404——
429——
503——
GET/api/v1/persona/{slug}/contractsPerson-to-procurement derivation (unavailable)
Parameters
NameInRequiredType
slugpathyesstring
Responses
StatusDescriptionSchema
429——
503——
Sectors4

CNAE sector aggregates, ratios and company listings

GET/api/v1/cnae/treeHierarchical CNAE tree
Responses
StatusDescriptionSchema
200CNAE treeCnaeTreeResponse
429——
503——
GET/api/v1/cnae/{code}CNAE code metadata
Parameters
NameInRequiredType
codepathyesstring
Responses
StatusDescriptionSchema
200CNAE metadataCnaeNode
404——
429——
503——
GET/api/v1/sector/{cnae}/companiesGet companies by CNAE sector code
Parameters
NameInRequiredType
cnaepathyesstring
limitquerynointeger
offsetquerynointeger
sortquerynostring
provincequerynostring
Responses
StatusDescriptionSchema
200Companies in sectorSectorCompaniesResponse
400——
422——
429——
503Required sector-company index unavailableErrorResponse
GET/api/v1/sector/{cnae}/ratiosGet sector aggregated ratios
Parameters
NameInRequiredType
cnaepathyesstring
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200Sector ratiosSectorRatiosResponse
304Not modified; the verified projection generation and legal source authority are unchanged.—
404——
429——
503——
BORME2

Daily BORME publications, multi-source timeline and registry events

GET/api/v1/daily/{date}Get BORME daily summary
Parameters
NameInRequiredType
datepathyesstring
Responses
StatusDescriptionSchema
200Daily summary with acts listDailySummary
404——
429——
503——
GET/api/v1/summary/date/{date}Get a BORME daily summary through the legacy alias
Parameters
NameInRequiredType
datepathyesstring
Responses
StatusDescriptionSchema
200Daily summary with acts listDailySummary
404——
429——
Public Procurement8

Public procurement awards (PLACSP) and grants (BDNS)

GET/api/v1/contracts/top-companiesCorporate suppliers ranked by PLACSP award procedures
Parameters
NameInRequiredType
limitquerynointeger
Responses
StatusDescriptionSchema
200Sanitized corporate supplier rankingTenderSupplierResponse
400——
422——
429——
500——
503PLACSP public projection unavailable—
GET/api/v1/contracts/top-companies.csvCorporate suppliers by award procedures (CSV)
Parameters
NameInRequiredType
limitquerynointeger
Responses
StatusDescriptionSchema
200CSV download—
400——
422——
429——
500——
503PLACSP public projection unavailable—
GET/api/v1/contracts/top-personsTop persons by PLACSP-signatory companies
Responses
StatusDescriptionSchema
429——
503——
GET/api/v1/contracts/top-persons.csvTop persons by PLACSP-signatory companies (CSV)
Responses
StatusDescriptionSchema
400——
429——
503——
GET/api/v1/tendersSearch public procurement notices
Parameters
NameInRequiredType
qquerynostring
cpvquerynostring
phasequerynostring
provincequerynostring
buyer_nifquerynostring
supplier_cifquerynostring
open_onlyquerynoboolean
amount_kindquerynostring
min_amount_eurquerynonumber
max_amount_eurquerynonumber
published_fromquerynostring
published_toquerynostring
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200Sanitized notice pageTenderSearchResponse
400——
422A validly typed value is outside its documented range, a lower bound exceeds its upper bound, full-text is combined with a structured filter, CPV plus a non-date structured filter requires an offline compound projection, or supplier_cif is combined with open_only or any monetary filter before its compound offline projection existsErrorResponse
429——
500——
503PLACSP dataset, public FTS, CPV prefix projection or exact CPV-date index unavailableErrorResponse
GET/api/v1/tenders/statsGet non-personal procurement coverage metrics
Responses
StatusDescriptionSchema
200Coverage and quality metricsTenderStats
400——
429——
500——
503——
GET/api/v1/tenders/suppliersList corporate suppliers by award count
Parameters
NameInRequiredType
limitquerynointeger
Responses
StatusDescriptionSchema
200Sanitized corporate supplier rankingTenderSupplierResponse
400——
422limit is a valid integer but outside 1..50ErrorResponse
429——
500——
503——
GET/api/v1/tenders/{key}Get a sanitized procurement notice
Parameters
NameInRequiredType
keypathyesstring
Responses
StatusDescriptionSchema
200Sanitized notice detail—
400——
404——
429——
500——
503——
Graph2

Corporate and person-to-company relationship graphs. Every emitted record retains the source-specific terms authorized by the active public source catalog; no blanket relicensing applies.

GET/api/v1/grafo/persona/{slug}Get person-to-company graph
Parameters
NameInRequiredType
slugpathyesstring
limitquerynointeger
Responses
StatusDescriptionSchema
200Person graphPersonGraphResponse
400——
404——
422——
429——
503——
GET/api/v1/grafo/{slug}Get corporate graph for a company
Parameters
NameInRequiredType
slugpathyesstring
max_childrenquerynointeger
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200Company corporate graphCompanyGraphResponse
304The admitted graph projection has not changed.—
400——
404——
422——
429——
503——
Datasets8

Bulk exports (CSV / JSON / aggregated stats)

GET/api/v1/ccaa/statsGet CCAA aggregates through the suffix-less legacy alias
Parameters
NameInRequiredType
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200CCAA statsCcaaStatsResponse
304The canonical CCAA representation and shared stats generation have not changed—
429——
503Offline projection missing or stale—
GET/api/v1/ccaa/stats.jsonAggregates by autonomous community (CCAA)
Parameters
NameInRequiredType
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200CCAA statsCcaaStatsResponse
304The CCAA representation and shared stats generation have not changed—
429——
503——
GET/api/v1/datasets/publicList generation-bound public company downloads
Parameters
NameInRequiredType
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200Atomic catalog of the three admitted public company downloadsPublicCompanyDownloadCatalog
304The generation-bound download catalog has not changed—
429——
503——
GET/api/v1/export/companiesRequest an offline company export artifact (currently unavailable)
Parameters
NameInRequiredType
provinciaquerynostring
tipoquerynostring
añoquerynostring
limitquerynointeger
offsetquerynointeger
formatoquerynostring
Responses
StatusDescriptionSchema
400——
401——
403Scope or paid plan required—
429Export-specific rate limit exceeded—
503A pre-sanitized offline export artifact is requiredOfflineProjectionError
GET/api/v1/export/eventsBulk BORME export (offline artifact required)
Responses
StatusDescriptionSchema
503Pre-sanitized offline artifact is not availableOfflineProjectionError
GET/api/v1/sectores/statsGet CNAE-sector aggregates through the suffix-less legacy alias
Parameters
NameInRequiredType
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200Sector statsSectorStatsResponse
304The canonical sector representation and shared stats generation have not changed—
429——
503Offline projection missing or stale—
GET/api/v1/sectores/stats.csvAggregates by CNAE sector (CSV)
Parameters
NameInRequiredType
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200Sector stats CSV—
304The bounded sector CSV representation and shared stats generation have not changed—
429——
503Offline projection missing or stale—
GET/api/v1/sectores/stats.jsonAggregates by CNAE sector
Parameters
NameInRequiredType
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200Sector statsSectorStatsResponse
304The sector representation and shared stats generation have not changed—
429——
503——
Sources2

Source catalog metadata, freshness and integration status

GET/api/v1/sources/freshnessPer-source freshness map
Parameters
NameInRequiredType
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200Freshness map—
304The authorized freshness representation and shared stats generation have not changed—
429——
503The required offline freshness projection is absent, or the public-source legal policy cannot produce an authorized projection. This endpoint fails closed and never falls back to live connector telemetry.OfflineProjectionError
GET/api/v1/sources/statusMinimized public source metadata
Parameters
NameInRequiredType
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200Fail-closed public source projectionPublicSourceStatusResponse
304The minimized source-status representation and shared stats generation have not changed—
429——
503——
Integrations2

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

GET/api/v1/integrationsList public integration capabilities
Parameters
NameInRequiredType
capabilityquerynostring
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200Public integration catalogIntegrationListResponse
304The legal catalog and technical transport snapshot have not changed—
400——
429——
503——
GET/api/v1/integrations/{slug}Get one public integration contract
Parameters
NameInRequiredType
slugpathyesstring
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200Public integration metadataIntegrationDetailResponse
304The legal decision and technical transport snapshot have not changed—
400——
404——
429——
503——
System2

Service health and metadata

GET/api/v1/healthService health
Parameters
NameInRequiredType
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200Health responseHealthResponse
304The exact offline health representation and shared stats generation have not changed—
429——
503——
GET/api/v1/statsPublished public-dataset counters
Parameters
NameInRequiredType
If-None-Matchheadernostring
Responses
StatusDescriptionSchema
200Stats response—
304The company-public generation and bounded statistics representation have not changed.—
429——
503——
User57

Authenticated Panel Pro endpoints — segments, lists, notes, tags, exports, audit. Requires session cookie (browser) and X-CSRF-Token header for mutations.

GET/api/v1/csrfGet a live same-origin CSRF token
Responses
StatusDescriptionSchema
200Session CSRF state—
POST/api/v1/persons/lookupRun an authenticated KYC documentary lookup
Parameters
NameInRequiredType
X-CSRF-Tokenheaderyesstring
Request body

application/json — KycPersonLookupRequest (required)

Responses
StatusDescriptionSchema
200Documentary lookup result with disclaimer and usageKycPersonLookupResponse
400——
401——
402Plan or monthly KYC quota does not permit the lookup—
403Invalid CSRF token—
429——
503KYC helper unavailable—
GET/api/v1/persons/lookup/historyGet the caller's redacted KYC lookup history
Parameters
NameInRequiredType
limitquerynointeger
offsetquerynointeger
Responses
StatusDescriptionSchema
200Redacted KYC lookup historyKycPersonLookupHistoryResponse
400——
401——
402Plan does not include KYC lookup—
422——
503KYC helper unavailable—
GET/api/v1/persons/lookup/usageGet the caller's KYC lookup allowance and usage
Responses
StatusDescriptionSchema
200KYC tier and usage metadataKycPersonLookupUsageResponse
401——
503KYC helper unavailable—
POST/api/v1/resend-verificationResend the account email-verification link
Parameters
NameInRequiredType
X-CSRF-Tokenheaderyesstring
Responses
StatusDescriptionSchema
200Verification email accepted by transportVerificationDispatchResponse
401——
403Invalid CSRF token—
429——
502Mail transport unavailable—
GET/api/v1/user/api-credentialsList API credential metadata
Parameters
NameInRequiredType
limitquerynointeger
cursorquerynostring
Responses
StatusDescriptionSchema
200Credential metadata and allowed scope catalog—
400——
401——
422——
503Account, credential schema or cursor-signing service unavailable—
POST/api/v1/user/api-credentialsCreate an API credential
Parameters
NameInRequiredType
X-CSRF-Tokenheaderyesstring
Idempotency-Keyheaderyesstring
Request body

application/json — ApiCredentialCreateRequest (required)

Responses
StatusDescriptionSchema
201Credential created, or its encrypted one-time response replayed for the same key and payloadApiCredentialOneTimeResponse
400——
401——
403Invalid CSRF token—
409Active credential limit, Idempotency-Key payload conflict, or expired replay window—
429——
503Credential pepper, idempotency encryption keyring/schema, or account service unavailable—
DELETE/api/v1/user/api-credentials/{id}Revoke one API credential
Parameters
NameInRequiredType
idpathyesinteger
X-CSRF-Tokenheaderyesstring
Responses
StatusDescriptionSchema
200Credential revokedCredentialRevokedResponse
401——
403Invalid CSRF token—
404——
429——
503Account security or credential schema unavailable—
POST/api/v1/user/api-credentials/{id}/rotateRotate one API credential
Parameters
NameInRequiredType
idpathyesinteger
X-CSRF-Tokenheaderyesstring
Idempotency-Keyheaderyesstring
Request body

application/json — ApiCredentialRotateRequest

Responses
StatusDescriptionSchema
200Rotated, or the exact replacement token replayed for the same key and payloadApiCredentialOneTimeResponse
400——
401——
403Invalid CSRF token—
404——
409Idempotency-Key payload conflict or expired replay window—
429——
503Credential pepper, idempotency encryption keyring/schema, or account service unavailable—
GET/api/v1/user/auditAudit log (MAX/Enterprise only)
Parameters
NameInRequiredType
limitquerynointeger
offsetquerynointeger
Responses
StatusDescriptionSchema
200Audit entriesUserAuditResponse
400——
401——
402Upgrade required—
422——
GET/api/v1/user/exportsExport history + monthly usage
Parameters
NameInRequiredType
limitquerynointeger
Responses
StatusDescriptionSchema
200Recent + usage_summary {used, max, remaining, pct, unlimited}UserExportListResponse
400——
401——
422——
GET/api/v1/user/exports/usageMonthly export quota usage only
Responses
StatusDescriptionSchema
200Usage summaryExportUsageResponse
GET/api/v1/user/listsList user lists
Responses
StatusDescriptionSchema
200Lists with tier_maxUserListListResponse
POST/api/v1/user/listsCreate list
Parameters
NameInRequiredType
X-CSRF-Tokenheaderyesstring
Request body

application/json — UserListCreateRequest (required)

Responses
StatusDescriptionSchema
201CreatedUserListCreatedResponse
400——
401——
403Invalid CSRF—
GET/api/v1/user/lists/{id}Get list + items
Parameters
NameInRequiredType
idpathyesinteger
Responses
StatusDescriptionSchema
200List + itemsUserListDetail
PUT/api/v1/user/lists/{id}Replace mutable list fields
Parameters
NameInRequiredType
idpathyesinteger
X-CSRF-Tokenheaderyesstring
Request body

application/json — UserListUpdateRequest (required)

Responses
StatusDescriptionSchema
200UpdatedOkResponse
400——
401——
403Invalid CSRF—
404——
PATCH/api/v1/user/lists/{id}Patch mutable list fields
Parameters
NameInRequiredType
idpathyesinteger
X-CSRF-Tokenheaderyesstring
Request body

application/json — UserListUpdateRequest (required)

Responses
StatusDescriptionSchema
200UpdatedOkResponse
400——
401——
403Invalid CSRF—
404——
DELETE/api/v1/user/lists/{id}Delete list and its items
Parameters
NameInRequiredType
idpathyesinteger
X-CSRF-Tokenheaderyesstring
Responses
StatusDescriptionSchema
200DeletedOkResponse
401——
403Invalid CSRF—
POST/api/v1/user/lists/{id}/itemsAdd item to list
Parameters
NameInRequiredType
idpathyesinteger
X-CSRF-Tokenheaderyesstring
Request body

application/json — UserListItemCreateRequest (required)

Responses
StatusDescriptionSchema
201AddedOkResponse
400——
401——
403Invalid CSRF—
404——
DELETE/api/v1/user/lists/{id}/items/{item_id}Remove item from list
Parameters
NameInRequiredType
idpathyesinteger
item_idpathyesinteger
X-CSRF-Tokenheaderyesstring
Responses
StatusDescriptionSchema
200RemovedOkResponse
401——
403Invalid CSRF—
404——
GET/api/v1/user/meCurrent authenticated user
Responses
StatusDescriptionSchema
200User profileUserMeResponse
401——
GET/api/v1/user/notesRecent notes
Parameters
NameInRequiredType
limitquerynointeger
Responses
StatusDescriptionSchema
200NotesUserNoteListResponse
400——
401——
422——
POST/api/v1/user/notesCreate private note
Parameters
NameInRequiredType
X-CSRF-Tokenheaderyesstring
Request body

application/json — UserNoteCreateRequest (required)

Responses
StatusDescriptionSchema
201CreatedUserNoteCreatedResponse
400——
401——
403Invalid CSRF—
GET/api/v1/user/notes/for/{type}/{id}Notes for a target
Parameters
NameInRequiredType
typepathyesstring
idpathyesstring
Responses
StatusDescriptionSchema
200Notes listUserNotesForTargetResponse
GET/api/v1/user/notes/{id}Get note
Parameters
NameInRequiredType
idpathyesinteger
Responses
StatusDescriptionSchema
200NoteUserNote
PUT/api/v1/user/notes/{id}Replace mutable note fields
Parameters
NameInRequiredType
idpathyesinteger
X-CSRF-Tokenheaderyesstring
Request body

application/json — UserNoteUpdateRequest (required)

Responses
StatusDescriptionSchema
200UpdatedOkResponse
400——
401——
403Invalid CSRF—
404——
PATCH/api/v1/user/notes/{id}Patch mutable note fields
Parameters
NameInRequiredType
idpathyesinteger
X-CSRF-Tokenheaderyesstring
Request body

application/json — UserNoteUpdateRequest (required)

Responses
StatusDescriptionSchema
200UpdatedOkResponse
400——
401——
403Invalid CSRF—
404——
DELETE/api/v1/user/notes/{id}Delete note
Parameters
NameInRequiredType
idpathyesinteger
X-CSRF-Tokenheaderyesstring
Responses
StatusDescriptionSchema
200DeletedOkResponse
401——
403Invalid CSRF—
GET/api/v1/user/orgGet the current organization, seats and visible members
Responses
StatusDescriptionSchema
200Organization contextUserOrganizationResponse
401——
503Organization service unavailable—
POST/api/v1/user/orgCreate an organization
Parameters
NameInRequiredType
X-CSRF-Tokenheaderyesstring
Request body

application/json — UserOrganizationNameRequest (required)

Responses
StatusDescriptionSchema
201Organization createdOrganizationCreatedResponse
400——
401——
402Plan does not include teams—
403Invalid CSRF—
409User already belongs to an organization—
503Organization service unavailable—
PUT/api/v1/user/orgRename the current organization
Parameters
NameInRequiredType
X-CSRF-Tokenheaderyesstring
Request body

application/json — UserOrganizationNameRequest (required)

Responses
StatusDescriptionSchema
200Organization renamedOkResponse
400——
401——
403Owner permission or CSRF required—
404——
503Organization service unavailable—
POST/api/v1/user/org/invitesCreate or renew an organization invitation
Parameters
NameInRequiredType
X-CSRF-Tokenheaderyesstring
Request body

application/json — UserOrganizationInviteRequest (required)

Responses
StatusDescriptionSchema
201Invitation created or renewed without tokenOrganizationInviteCreatedResponse
400——
401——
403Owner/admin permission or CSRF required—
409No organization, duplicate member or no free seat—
429——
503Organization or email service unavailable—
DELETE/api/v1/user/org/invites/{id}Cancel a pending organization invitation
Parameters
NameInRequiredType
idpathyesinteger
X-CSRF-Tokenheaderyesstring
Responses
StatusDescriptionSchema
200Invitation cancelledOkResponse
401——
403Owner/admin permission or CSRF required—
404——
503Organization service unavailable—
POST/api/v1/user/org/invites/{id}/resendRotate and resend an organization invitation
Parameters
NameInRequiredType
idpathyesinteger
X-CSRF-Tokenheaderyesstring
Responses
StatusDescriptionSchema
200Invitation resentEmailDispatchResponse
401——
403Owner/admin permission or CSRF required—
404——
409No free seat for an expired invitation—
429——
503Organization or email service unavailable—
POST/api/v1/user/org/leaveLeave the current organization
Parameters
NameInRequiredType
X-CSRF-Tokenheaderyesstring
Responses
StatusDescriptionSchema
200Organization leftOkResponse
401——
403Invalid CSRF—
404——
409Owner cannot leave before transferring ownership—
503Organization service unavailable—
PUT/api/v1/user/org/members/{id}Change an organization member role
Parameters
NameInRequiredType
idpathyesinteger
X-CSRF-Tokenheaderyesstring
Request body

application/json — UserOrganizationMemberRoleRequest (required)

Responses
StatusDescriptionSchema
200Role updatedOkResponse
400——
401——
403Owner permission or CSRF required—
404——
503Organization service unavailable—
DELETE/api/v1/user/org/members/{id}Remove a member from the organization
Parameters
NameInRequiredType
idpathyesinteger
X-CSRF-Tokenheaderyesstring
Responses
StatusDescriptionSchema
200Member removedOkResponse
400——
401——
403Owner/admin permission or CSRF required—
404——
503Organization service unavailable—
GET/api/v1/user/personaCurrent persona config + available list
Responses
StatusDescriptionSchema
200Persona configUserPersonaResponse
401——
POST/api/v1/user/personaSet persona_primary
Parameters
NameInRequiredType
X-CSRF-Tokenheaderyesstring
Request body

application/json — UserPersonaUpdateRequest (required)

Responses
StatusDescriptionSchema
200UpdatedUserPersonaSelectedResponse
400Invalid persona slug—
401——
403Invalid CSRF—
GET/api/v1/user/segmentsList user segments
Parameters
NameInRequiredType
pinnedquerynostring
limitquerynointeger
Responses
StatusDescriptionSchema
200Segments list with tier_maxUserSegmentListResponse
400——
401——
422——
POST/api/v1/user/segmentsCreate segment
Parameters
NameInRequiredType
X-CSRF-Tokenheaderyesstring
Request body

application/json — UserSegmentCreateRequest (required)

Responses
StatusDescriptionSchema
201CreatedUserSegmentCreatedResponse
400Malformed/unknown filter, legally unavailable legacy filter, missing effective anchor or tier limitErrorResponse
401——
422Individually valid filters do not have a safe indexed combinationErrorResponse
GET/api/v1/user/segments/{id}Get segment
Parameters
NameInRequiredType
idpathyesinteger
Responses
StatusDescriptionSchema
200SegmentUserSegment
404——
PUT/api/v1/user/segments/{id}Replace mutable segment fields
Parameters
NameInRequiredType
idpathyesinteger
X-CSRF-Tokenheaderyesstring
Request body

application/json — UserSegmentUpdateRequest (required)

Responses
StatusDescriptionSchema
200UpdatedOkResponse
400Malformed/unknown or legally unavailable filterErrorResponse
401——
403Invalid CSRF—
404——
422Individually valid filters do not have a safe indexed combinationErrorResponse
PATCH/api/v1/user/segments/{id}Patch mutable segment fields
Parameters
NameInRequiredType
idpathyesinteger
X-CSRF-Tokenheaderyesstring
Request body

application/json — UserSegmentUpdateRequest (required)

Responses
StatusDescriptionSchema
200UpdatedOkResponse
400Malformed/unknown or legally unavailable filterErrorResponse
401——
403Invalid CSRF—
404——
422Individually valid filters do not have a safe indexed combinationErrorResponse
DELETE/api/v1/user/segments/{id}Delete segment
Parameters
NameInRequiredType
idpathyesinteger
X-CSRF-Tokenheaderyesstring
Responses
StatusDescriptionSchema
200DeletedOkResponse
401——
403Invalid CSRF—
POST/api/v1/user/segments/{id}/pinToggle pin
Parameters
NameInRequiredType
idpathyesinteger
X-CSRF-Tokenheaderyesstring
Responses
StatusDescriptionSchema
200New pinned stateUserSegmentPinResponse
401——
403Invalid CSRF—
404——
POST/api/v1/user/segments/{id}/runExecute segment filters → companies
Parameters
NameInRequiredType
idpathyesinteger
limitquerynointeger
X-CSRF-Tokenheaderyesstring
Responses
StatusDescriptionSchema
200Bounded result rows; count equals rows.length and is not a global totalUserSegmentRunResponse
400Malformed/unknown or legally unavailable saved filterErrorResponse
401——
403Invalid CSRF—
404——
422Saved filters are valid individually but lack a safe indexed combinationErrorResponse
503Canonical authority, legal layer, immutable company sidecar or bounded query unavailableErrorResponse
GET/api/v1/user/tagsList user tags with counts
Responses
StatusDescriptionSchema
200Tags + statsUserTagListResponse
POST/api/v1/user/tagsCreate tag
Parameters
NameInRequiredType
X-CSRF-Tokenheaderyesstring
Request body

application/json — UserTagCreateRequest (required)

Responses
StatusDescriptionSchema
201CreatedUserTagCreatedResponse
400——
401——
403Invalid CSRF—
DELETE/api/v1/user/tags/{id}Delete tag and assignments
Parameters
NameInRequiredType
idpathyesinteger
X-CSRF-Tokenheaderyesstring
Responses
StatusDescriptionSchema
200DeletedOkResponse
401——
403Invalid CSRF—
POST/api/v1/user/tags/{id}/assignAssign tag to target
Parameters
NameInRequiredType
idpathyesinteger
X-CSRF-Tokenheaderyesstring
Request body

application/json — UserTagAssignmentRequest (required)

Responses
StatusDescriptionSchema
200AssignedOkResponse
400——
401——
403Invalid CSRF—
404——
POST/api/v1/user/tags/{id}/unassignUnassign tag from target
Parameters
NameInRequiredType
idpathyesinteger
X-CSRF-Tokenheaderyesstring
Request body

application/json — UserTagAssignmentRequest (required)

Responses
StatusDescriptionSchema
200UnassignedOkResponse
400——
401——
403Invalid CSRF—
404——
GET/api/v1/user/webhooksList outbound webhook metadata
Responses
StatusDescriptionSchema
200Webhook metadata—
401——
503Account or webhook security schema unavailable—
POST/api/v1/user/webhooksCreate an outbound webhook
Parameters
NameInRequiredType
X-CSRF-Tokenheaderyesstring
Idempotency-Keyheaderyesstring
Request body

application/json — OutboundWebhookCreateRequest (required)

Responses
StatusDescriptionSchema
201Created, or the exact signing secret replayed for the same key and payloadOutboundWebhookOneTimeResponse
400——
401——
403Invalid CSRF token—
409Idempotency-Key payload conflict or expired replay window—
429——
503Webhook service, secret keyring, or durable idempotency schema/keyring unavailable—
PATCH/api/v1/user/webhooks/{id}Update an outbound webhook
Parameters
NameInRequiredType
idpathyesinteger
X-CSRF-Tokenheaderyesstring
Request body

application/json — OutboundWebhookUpdateRequest (required)

Responses
StatusDescriptionSchema
200Updated metadataWebhookUpdatedResponse
400——
401——
403Invalid CSRF token—
404——
429——
503Account security or webhook schema unavailable—
DELETE/api/v1/user/webhooks/{id}Delete an outbound webhook
Parameters
NameInRequiredType
idpathyesinteger
X-CSRF-Tokenheaderyesstring
Responses
StatusDescriptionSchema
200DeletedDeletedResponse
401——
403Invalid CSRF token—
404——
429——
503Account security or webhook schema unavailable—
POST/api/v1/user/webhooks/{id}/rotateRotate an outbound webhook signing secret
Parameters
NameInRequiredType
idpathyesinteger
X-CSRF-Tokenheaderyesstring
Idempotency-Keyheaderyesstring
Responses
StatusDescriptionSchema
200Rotated, or the exact replacement signing secret replayed for the same keyOutboundWebhookOneTimeResponse
400——
401——
403Invalid CSRF token—
404——
409Idempotency-Key payload conflict or expired replay window—
429——
503Account security, encryption keyring or webhook schema unavailable—
Billing8

Session-bound Stripe checkout, invoices and portal contracts. External actions are bounded, idempotent and never exposed through the public MCP.

GET/api/v1/billing/invoicesList the authenticated user's invoices and subscription
Responses
StatusDescriptionSchema
200Local billing projectionBillingInvoicesResponse
401——
429——
GET/api/v1/billing/portalRedirect to the authenticated user's Stripe portal
Responses
StatusDescriptionSchema
302Redirect to Stripe Customer Portal—
400——
401——
429——
503Action budget or Stripe unavailable—
POST/api/v1/billing/portalCreate a Stripe portal session as JSON
Parameters
NameInRequiredType
X-CSRF-Tokenheaderyesstring
Responses
StatusDescriptionSchema
200Stripe Customer Portal URLStripeSessionResponse
400——
401——
403Invalid CSRF token—
429——
503Action budget or Stripe unavailable—
POST/api/v1/checkoutCreate a subscription Checkout session
Parameters
NameInRequiredType
X-CSRF-Tokenheaderyesstring
Idempotency-Keyheadernostring
Request body

application/json (required)

Responses
StatusDescriptionSchema
200Checkout URL and Stripe session idStripeSessionResponse
400——
401——
403Invalid CSRF token—
413Request body too large—
429——
503Action budget or Stripe unavailable—
POST/api/v1/credits/checkoutCreate an idempotent credit-pack Checkout session
Parameters
NameInRequiredType
X-CSRF-Tokenheaderyesstring
Idempotency-Keyheadernostring
Request body

application/json (required)

Responses
StatusDescriptionSchema
200Checkout URL and Stripe session idStripeSessionResponse
400——
401——
403Invalid CSRF token—
413Request body too large—
429——
503Action budget or Stripe unavailable—
POST/api/v1/donationCreate a one-time donation Checkout session
Parameters
NameInRequiredType
Idempotency-Keyheadernostring
Request body

application/json (required)

Responses
StatusDescriptionSchema
200Checkout URL and Stripe session idStripeSessionResponse
400——
413Request body too large—
429——
503Action budget or Stripe unavailable—
POST/api/v1/portalCreate a Stripe Customer Portal session through the legacy alias
Parameters
NameInRequiredType
X-CSRF-Tokenheadernostring
Request body

application/x-www-form-urlencoded

Responses
StatusDescriptionSchema
200Stripe Customer Portal URLStripeSessionResponse
400——
401——
403Invalid or missing CSRF tokenErrorResponse
429——
503Action-budget storage or Stripe Customer Portal is unavailableErrorResponse
POST/api/v1/stripe-webhookReceive a signed Stripe event
Parameters
NameInRequiredType
Stripe-Signatureheaderyesstring
Request body

application/json — StripeWebhookEventRequest (required)

Responses
StatusDescriptionSchema
200Event accepted, deliberately ignored, or already terminal. All response bodies are non-secret acknowledgements.—
400Signature missing/invalid, or the raw request stream cannot be read—
413Raw callback body exceeds 512 KiBRequestBodyTooLargeError
500Inbox persistence or event processing failed; Stripe must retry—
503Another worker owns an active lease or a signed OpenMercantil checkout cannot yet be resolved to its authoritative account owner; Stripe must retry—
Support2

Customer-support writes. Anonymous creation requires explicit privacy consent; replies require an authenticated owner session and CSRF. Ticket data is never exposed through the public MCP.

POST/api/v1/support/ticketCreate a customer-support ticket
Request body

application/json — SupportTicketCreateRequest (required)

Responses
StatusDescriptionSchema
201Ticket created; only its internal numeric id and non-secret public reference are returnedSupportTicketCreatedResponse
400Invalid JSON fields, validation failure or missing strict privacy consentSupportRequestErrorResponse
413Request body exceeds 32 KiBRequestBodyTooLargeError
429API plan quota exhausted or the per-IP ceiling of 5 ticket creations per hour was reachedSupportRequestErrorResponse
503The account database or migrated support schema is unavailable; creation fails closedSupportErrorResponse
POST/api/v1/support/ticket/{id}/replyReply to a support ticket owned by the authenticated user
Parameters
NameInRequiredType
idpathyesinteger
X-CSRF-Tokenheaderyesstring
Request body

application/json — SupportReplyRequest (required)

Responses
StatusDescriptionSchema
200Reply persistedOkResponse
400Reply validation failed or the ticket is closedSupportRequestErrorResponse
401——
403Invalid CSRF token, ticket not found under this account, or caller is not the ownerSupportErrorResponse
413Request body exceeds 32 KiBRequestBodyTooLargeError
429——
503The action-budget store, account database or migrated support schema is unavailable; reply fails closedSupportRequestErrorResponse
Legal7

Spanish mercantile-law layer (derecho mercantil): legislation corpus + article texts + act→norm bridge. Distributes the consolidated BOE legal corpus structured by OpenMercantil so LLMs and agents can cite it as a source. License: consolidated text from the BOE, reused under Ley 37/2007 (re-use of public sector information); the official version is always boe.es. Informational only — NOT legal advice. Court judgments are NOT exposed here (CENDOJ is kept as a citation-index only, per CGPJ Reglamento 3/2010); this layer distributes legislation + the act↔norm index.

POST/api/v1/empresa/{slug}/informe-legalCreate the authenticated user's redacted corporate legal report
Parameters
NameInRequiredType
slugpathyesstring
X-CSRF-Tokenheaderyesstring
Request body

application/json — LegalReportRequest

Responses
StatusDescriptionSchema
200Redacted documentary corporate report and server-owned charging resultLegalReportResponse
400——
401——
402Insufficient credits or the idempotent charge could not be completedLegalReportPaymentRequiredError
403Invalid or missing CSRF tokenErrorResponse
404Corporate subject not found or the slug is classified as a natural-person subjectErrorResponse
413Request body exceeds 32 KiBRequestBodyTooLargeError
429——
503Action-budget storage, legal source policy, report helper, account schema or credit ledger unavailable; generation fails closedErrorResponse
GET/api/v1/legal/act-mapBORME act type → governing norm bridge (full or single)
Responses
StatusDescriptionSchema
200Full act→norm map with license envelopeLegalActMapResponse
429——
503——
GET/api/v1/legal/act-map/{acto}Governing norm for a single BORME act type
Parameters
NameInRequiredType
actopathyesstring
Responses
StatusDescriptionSchema
200Single act→norm mappingLegalActMapEntry
404——
429——
503——
GET/api/v1/legal/article/{norm}/{n}Consolidated text of a single article
Parameters
NameInRequiredType
normpathyesstring
npathyesstring
Responses
StatusDescriptionSchema
200Consolidated article textLegalArticleResponse
404——
429——
503——
GET/api/v1/legal/normIndex mercantile-law norms through the singular legacy alias
Responses
StatusDescriptionSchema
200Norm index with license, attribution and disclaimer envelopeLegalNormsIndexResponse
429——
503——
GET/api/v1/legal/norm/{slug}Detail of a single mercantile-law norm (with act↔norm bridge)
Parameters
NameInRequiredType
slugpathyesstring
Responses
StatusDescriptionSchema
200Norm detail with key articles, regulated acts and a citable factLegalNormResponse
404——
429——
503——
GET/api/v1/legal/normsIndex of core Spanish mercantile-law norms
Responses
StatusDescriptionSchema
200Norm index with license/attribution/disclaimer envelopeLegalNormsIndexResponse
429——
503——

Try it

Developer reference

Base URLhttps://openmercantil.es
Rate limit

60 requests/minute and 200 requests/day per IP on the free tier; higher tiers up to 600/minute and 50,000/day

Key endpoints
  • GET/api/v1/search
  • GET/api/v1/company/{slug}
  • GET/api/v1/health

Availability

Uptime100%
Median latency596 ms
Last checkUp · 400 · Sep 2026

17 checks since Aug 2026. A person runs this check by hand, not an automated monitor.

Changelog

Spec version1.9.3
Tracked paths118
  • Aug 2026gained an OpenAPI spec and a status page

Tracking since Sep 2026. See every tracked change ↗ ·Subscribe with RSS ↗