openapi: 3.0.3 info: title: Companies by Jsonpage API version: 2.0.0 description: >- Company data API. v1 serves French SIREN and SIRET lookups; v2 serves every supported country with one format. v2 also completes and checks form input (/v2/autocomplete, /v2/validate), monitors companies (/v2/monitors, /v2/events) and delivers their changes as signed webhooks, described under x-webhooks since OpenAPI 3.0 has no webhooks section. servers: - url: https://companies.jsonpage.com description: Production security: - ApiKey: [] paths: /v1/companies/{siren}: get: summary: Look up a company by SIREN operationId: getCompany parameters: - name: siren in: path required: true schema: type: string pattern: '^[0-9]{9}$' responses: '200': description: Company found content: application/json: schema: $ref: '#/components/schemas/Company' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '429': $ref: '#/components/responses/TooManyRequests' '500': $ref: '#/components/responses/DataUnavailable' '503': $ref: '#/components/responses/Unavailable' /v1/establishments/{siret}: get: summary: Look up an establishment by SIRET operationId: getEstablishment parameters: - name: siret in: path required: true schema: type: string pattern: '^[0-9]{14}$' responses: '200': description: Establishment found content: application/json: schema: $ref: '#/components/schemas/Establishment' '400': $ref: '#/components/responses/BadRequest' '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '404': $ref: '#/components/responses/NotFound' '429': $ref: '#/components/responses/TooManyRequests' '500': $ref: '#/components/responses/DataUnavailable' '503': $ref: '#/components/responses/Unavailable' /v1/metadata: get: summary: Read stock metadata operationId: getMetadata responses: '200': description: Stock metadata content: application/json: schema: type: object additionalProperties: type: string '401': $ref: '#/components/responses/Unauthorized' '403': $ref: '#/components/responses/Forbidden' '429': $ref: '#/components/responses/TooManyRequests' '500': $ref: '#/components/responses/DataUnavailable' '503': $ref: '#/components/responses/Unavailable' /health/live: get: summary: Liveness check description: Answers as soon as the service runs. No API key. operationId: healthLive security: [] responses: '200': description: The service answers content: application/json: schema: type: object properties: status: type: string enum: [ok] /health/ready: get: summary: Readiness check description: Tells whether the service is ready to serve data. No API key. operationId: healthReady security: [] responses: '200': description: Ready content: application/json: schema: type: object properties: status: type: string enum: [ready] source_date: type: string last_sync_at: type: string '503': description: Not ready content: application/json: schema: type: object properties: error: type: string enum: [data_unavailable, data_stale] /health/sources: get: summary: State of the data description: State of the data for each country served, as shown on the status page. No API key. operationId: healthSources security: [] responses: '200': description: State of the data of every country served content: application/json: schema: type: object properties: status: type: string enum: [ok, degraded] checked_at: type: string format: date-time sources: type: array items: type: object properties: country: type: string name: type: string published_at: type: string status: type: string enum: [ok, stale, unknown] /v2/companies/{id}: get: summary: Look up a company by global identifier description: >- Returns the base record, identical in every country, plus the blocks requested with include. France (FR), Belgium (BE), Switzerland (CH) and the United Kingdom (GB) are available. Belgian enterprise numbers have 10 digits with a modulo-97 check (BE-0417497106); 0417.497.106, BE0417497106 and the old 9-digit form are accepted. Swiss identifiers are CH- and the 9 digits of the UID without the CHE prefix (CH-101374515 for CHE-101.374.515), whose last digit is a modulo-11 check (eCH-0097); CH-CHE-101.374.515 and CH-CHE-101.374.515 MWST are accepted. In Switzerland, activity and incorporated_on are null (not provided for Switzerland) and closed_on stays null for a closed entity. operationId: getCompanyV2 parameters: - $ref: '#/components/parameters/CompanyId' - $ref: '#/components/parameters/Include' - $ref: '#/components/parameters/Fields' - $ref: '#/components/parameters/IfNoneMatch' responses: '200': description: Company found headers: ETag: $ref: '#/components/headers/ETag' X-RateLimit-Remaining: $ref: '#/components/headers/RateLimitRemaining' content: application/json: schema: type: object required: [data, meta] properties: data: $ref: '#/components/schemas/V2Company' meta: $ref: '#/components/schemas/Meta' '304': $ref: '#/components/responses/V2NotModified' '400': $ref: '#/components/responses/V2BadRequest' '401': $ref: '#/components/responses/V2Unauthorized' '403': $ref: '#/components/responses/V2Forbidden' '404': $ref: '#/components/responses/V2NotFound' '429': $ref: '#/components/responses/V2TooManyRequests' '500': $ref: '#/components/responses/V2DataUnavailable' '503': $ref: '#/components/responses/V2Busy' /v2/companies/{id}/establishments: get: summary: List the establishments of a company description: >- Pages through the establishments of a company. Pass the next value of a page as after to get the following page; next is null on the last page. Returns 404 not_available_in_country when the register has no establishments. operationId: listEstablishmentsV2 parameters: - $ref: '#/components/parameters/CompanyId' - $ref: '#/components/parameters/Limit' - $ref: '#/components/parameters/After' - $ref: '#/components/parameters/IfNoneMatch' responses: '200': description: One page of establishments headers: ETag: $ref: '#/components/headers/ETag' content: application/json: schema: type: object required: [data, meta] properties: data: $ref: '#/components/schemas/EstablishmentPage' meta: $ref: '#/components/schemas/Meta' '304': $ref: '#/components/responses/V2NotModified' '400': $ref: '#/components/responses/V2BadRequest' '401': $ref: '#/components/responses/V2Unauthorized' '403': $ref: '#/components/responses/V2Forbidden' '404': $ref: '#/components/responses/V2NotFound' '429': $ref: '#/components/responses/V2TooManyRequests' '500': $ref: '#/components/responses/V2DataUnavailable' '503': $ref: '#/components/responses/V2Busy' /v2/companies: get: summary: Search companies by name, or find a registry number in every country served description: >- Give either q or registry_id; q takes precedence when both are given. With q (name search), every word of 2 characters or more must appear in the company name, the last word as a prefix of 3 letters or more ("peug" finds PEUGEOT). Case, accents and punctuation are ignored. Results come in this order: exact names first (legal forms such as SA, SAS, SARL, LTD or PLC are ignored when comparing, so "peugeot" finds PEUGEOT SA first), then active companies, then companies before sole traders, then relevance. Very common words are served without relevance ranking after 400 ms, so that results stay fast. Without country, every country with a name index is searched. Results are base records, as returned by GET /v2/companies/{id}; include is not applied. The whole search counts as one request. Units whose publication is restricted (diffusion status P) have no name and cannot be found by name. With registry_id, for clients that only know the national number: lists the companies of every country served that carry this number, usually one; an empty list if none, sorted by identifier. operationId: searchCompaniesV2 parameters: - $ref: '#/components/parameters/NameQuery' - $ref: '#/components/parameters/SearchCountry' - $ref: '#/components/parameters/SearchStatus' - $ref: '#/components/parameters/SearchLimit' - $ref: '#/components/parameters/RegistryId' - $ref: '#/components/parameters/IfNoneMatch' responses: '200': description: Matching companies (name search, best match first; registry_id, sorted by identifier) headers: ETag: $ref: '#/components/headers/ETag' content: application/json: schema: type: object required: [data, meta] properties: data: type: array items: $ref: '#/components/schemas/V2Company' meta: $ref: '#/components/schemas/Meta' '304': $ref: '#/components/responses/V2NotModified' '400': description: query_too_short (no word of 2 characters or more in q) or invalid_parameter (neither q nor registry_id, or limit, status out of range) content: application/json: schema: $ref: '#/components/schemas/V2Error' '401': $ref: '#/components/responses/V2Unauthorized' '403': $ref: '#/components/responses/V2Forbidden' '404': description: country_not_supported (a country in country has no name index) content: application/json: schema: $ref: '#/components/schemas/V2Error' '429': $ref: '#/components/responses/V2TooManyRequests' '500': $ref: '#/components/responses/V2DataUnavailable' '503': description: server_busy, or search_unavailable when no name index is loaded yet headers: Retry-After: schema: type: string content: application/json: schema: $ref: '#/components/schemas/V2Error' /v2/companies/batch: post: summary: Look up up to 100 companies in one call description: >- Each company counts as one request against the plan rate limit. The response keeps the requested order; each item has data, or error when the identifier is invalid or the company is not found. The body is a JSON object of at most 64 KB with ids and include only; any other field, or an unreadable body, returns 400 invalid_json. operationId: batchCompaniesV2 requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/BatchRequest' example: ids: [FR-552100554, FR-000000001] include: [vat] responses: '200': description: One item per requested identifier, in order content: application/json: schema: type: object required: [data, meta] properties: data: type: array items: $ref: '#/components/schemas/BatchItem' meta: $ref: '#/components/schemas/Meta' '400': $ref: '#/components/responses/V2BadRequest' '401': $ref: '#/components/responses/V2Unauthorized' '403': $ref: '#/components/responses/V2Forbidden' '429': $ref: '#/components/responses/V2TooManyRequests' '503': $ref: '#/components/responses/V2Busy' /v2/monitors: get: summary: List the monitored companies description: >- Lists the companies monitored by the account, sorted by identifier. When a page is full, next is the identifier of its last company: pass it to after for the next page; next is null on the last page. meta.count is the number of monitored companies and meta.limit the plan limit (Free 2, Standard 1,000, Pro 10,000). Counts as one request. operationId: listMonitorsV2 parameters: - name: after in: query required: false description: The next value of the previous page (a company identifier). schema: type: string example: FR-552100554 - $ref: '#/components/parameters/MonitorLimit' responses: '200': description: One page of monitored companies content: application/json: schema: $ref: '#/components/schemas/MonitorList' '400': $ref: '#/components/responses/V2BadRequest' '401': $ref: '#/components/responses/V2Unauthorized' '403': $ref: '#/components/responses/V2Forbidden' '429': $ref: '#/components/responses/V2TooManyRequests' '500': $ref: '#/components/responses/V2DataUnavailable' '503': $ref: '#/components/responses/V2MonitoringUnavailable' /v2/monitors/{id}: put: summary: Start monitoring a company description: >- Adds the company to the account's monitoring list. The state recorded now is the baseline: later checks compare the company with the official company registers, legal notices, beneficial ownership information and the sanctions lists, and record each difference as an event; no event is created for the past. Idempotent: 201 when the company is added, 200 when it was already monitored (also when the plan limit is reached). Counts as one request. operationId: addMonitorV2 parameters: - $ref: '#/components/parameters/CompanyId' responses: '200': description: The company was already monitored content: application/json: schema: $ref: '#/components/schemas/MonitorResult' example: data: { company_id: FR-552100554, created: false } '201': description: The company is now monitored content: application/json: schema: $ref: '#/components/schemas/MonitorResult' example: data: { company_id: FR-552100554, created: true } '400': $ref: '#/components/responses/V2BadRequest' '401': $ref: '#/components/responses/V2Unauthorized' '403': description: monitor_limit_reached (the plan monitors up to 2, 1,000 or 10,000 companies) or ip_not_allowed (request from an IP address outside the account's allowlist) content: application/json: schema: $ref: '#/components/schemas/V2Error' '404': description: not_found (no company with this identifier) content: application/json: schema: $ref: '#/components/schemas/V2Error' '429': $ref: '#/components/responses/V2TooManyRequests' '500': $ref: '#/components/responses/V2DataUnavailable' '503': $ref: '#/components/responses/V2MonitoringUnavailable' delete: summary: Stop monitoring a company description: Removes the company from the monitoring list. Events already recorded stay readable. Counts as one request. operationId: removeMonitorV2 parameters: - $ref: '#/components/parameters/CompanyId' responses: '204': description: The company is no longer monitored '400': $ref: '#/components/responses/V2BadRequest' '401': $ref: '#/components/responses/V2Unauthorized' '403': $ref: '#/components/responses/V2Forbidden' '404': description: not_monitored (the account does not monitor this company) content: application/json: schema: $ref: '#/components/schemas/V2Error' '429': $ref: '#/components/responses/V2TooManyRequests' '500': $ref: '#/components/responses/V2DataUnavailable' '503': $ref: '#/components/responses/V2MonitoringUnavailable' /v2/events: get: summary: List the detected events description: >- Lists the events of the account's monitored companies, oldest first. Event identifiers increase but are not necessarily consecutive. Pass the identifier of the last event processed to after; next is the identifier of the last event of the page, or null when there is no new event (keep your own cursor then). Events are kept 90 days. Webhook test events (ping) are not listed. Counts as one request. operationId: listEventsV2 parameters: - name: after in: query required: false description: Return the events after this one. Omit to start from the oldest event kept. schema: type: string pattern: '^evt_[0-9]+$' example: evt_41 - $ref: '#/components/parameters/MonitorLimit' - name: company_id in: query required: false description: Return only the events of this company (global identifier). A company no longer in the register keeps its events. schema: type: string example: FR-552100554 responses: '200': description: One page of events, oldest first content: application/json: schema: $ref: '#/components/schemas/EventList' '400': description: invalid_parameter (limit out of range, or after is not an event id such as evt_42), or invalid_identifier (company_id is not a global identifier) content: application/json: schema: $ref: '#/components/schemas/V2Error' '401': $ref: '#/components/responses/V2Unauthorized' '403': $ref: '#/components/responses/V2Forbidden' '429': $ref: '#/components/responses/V2TooManyRequests' '500': $ref: '#/components/responses/V2DataUnavailable' '503': $ref: '#/components/responses/V2MonitoringUnavailable' /v2/autocomplete: get: summary: Suggest companies while the user types description: >- For forms that complete as the user types. Answers from the name index only, without reading the full record, in a few milliseconds on the server. Words follow the name search rules of GET /v2/companies?q=: every word of 2 characters or more must appear in the name, the last word as a prefix. When q is a registry number (SIREN, SIRET, Belgian enterprise number, Swiss UID such as CHE-101.374.515 or UK company number), the matching company is returned directly; a 14-digit SIRET returns its company. Order: exact names first, then active companies, then companies before sole traders. Counts as one request. Call it from your backend (never expose the API key in the browser) and debounce the input (about 150 ms). operationId: autocompleteV2 parameters: - name: q in: query required: true description: Text typed by the user, a name or a registry number. schema: type: string example: carrefour - $ref: '#/components/parameters/SearchCountry' - name: status in: query required: false description: active keeps active companies only (default); any keeps every status. schema: type: string enum: [active, any] default: active - name: limit in: query required: false description: Maximum number of suggestions. schema: type: integer minimum: 1 maximum: 20 default: 8 - $ref: '#/components/parameters/IfNoneMatch' responses: '200': description: Suggestions, best match first headers: ETag: $ref: '#/components/headers/ETag' content: application/json: schema: type: object required: [data] properties: data: type: array items: $ref: '#/components/schemas/Suggestion' example: data: - { id: FR-652014051, name: CARREFOUR, status: active, postal_code: '91300', city: MASSY, kind: company } '304': $ref: '#/components/responses/V2NotModified' '400': description: query_too_short (no word of 2 characters or more in q) or invalid_parameter (status or limit out of range) content: application/json: schema: $ref: '#/components/schemas/V2Error' '401': $ref: '#/components/responses/V2Unauthorized' '403': $ref: '#/components/responses/V2Forbidden' '404': description: country_not_supported (a country in country has no name index) content: application/json: schema: $ref: '#/components/schemas/V2Error' '429': $ref: '#/components/responses/V2TooManyRequests' '500': $ref: '#/components/responses/V2DataUnavailable' '503': $ref: '#/components/responses/V2Busy' /v2/validate: get: summary: Check a company identifier, a SIRET and a VAT number in one call description: >- Give id, siret, vat, or any combination of them (at least one). Spaces, dots and hyphens are ignored in siret and vat. Each check is returned with its result; a check that depends on a failed one is omitted (a malformed SIRET is not looked up). valid is true only if every check returned is ok. company is the base record with its address (and its vat block when a VAT number was checked); it is returned even when the establishment or the company is closed, and is null when the identifiers do not point to the same company or the company is not found. French, Belgian and Swiss VAT numbers are supported: another country gives vat_country_supported=false. siret applies to France only. Use cases: client and supplier onboarding forms, invoices (supplier SIRET and VAT), simple company identity checks. Counts as one request. Responses are sent with Cache-Control: private, max-age=60. operationId: validateV2 parameters: - name: id in: query required: false description: Global company identifier. schema: type: string example: FR-652014051 - name: siret in: query required: false description: 14-digit SIRET of a French establishment. schema: type: string example: '55210055400039' - name: vat in: query required: false description: VAT number, French (FR…), Belgian (BE followed by the 10-digit enterprise number) or Swiss (the UID followed by MWST, TVA or IVA, such as CHE-105.909.036 MWST). schema: type: string example: FR14652014051 responses: '200': description: The result of every check (also when valid is false) content: application/json: schema: type: object required: [data] properties: data: $ref: '#/components/schemas/Validation' example: data: valid: true checks: - { code: id_format, ok: true, value: FR-652014051 } - { code: siren_key, ok: true, value: '652014051' } - { code: vat_format, ok: true, value: FR14652014051 } - { code: identifiers_match, ok: true, value: FR-652014051 } - { code: company_exists, ok: true, value: FR-652014051 } - { code: company_active, ok: true, value: active } - { code: vat_registered, ok: true, value: valid } company: id: FR-652014051 country: FR registry_id: '652014051' name: CARREFOUR status: active '400': description: invalid_parameter (none of id, siret and vat is given) content: application/json: schema: $ref: '#/components/schemas/V2Error' '401': $ref: '#/components/responses/V2Unauthorized' '403': $ref: '#/components/responses/V2Forbidden' '429': $ref: '#/components/responses/V2TooManyRequests' '500': $ref: '#/components/responses/V2DataUnavailable' '503': $ref: '#/components/responses/V2Busy' components: securitySchemes: ApiKey: type: apiKey in: header name: X-API-Key description: >- API key created in the dashboard; an account can hold several named keys (1, 3 or 10 depending on the plan). A rotated key keeps working for 24 hours. On the Pro plan, keys can be restricted to allowed IP addresses or ranges; other addresses get 403 ip_not_allowed. parameters: CompanyId: name: id in: path required: true description: >- Global identifier: ISO 3166-1 alpha-2 country code, a hyphen and the national registry number, for example FR-552100554, BE-0417497106, CH-101374515 or GB-00445790. schema: type: string pattern: '^[A-Za-z]{2}-.+$' example: FR-552100554 Include: name: include in: query required: false description: >- Comma-separated optional blocks. An unknown block returns 400 unknown_include. Blocks not yet available in a country are reported in meta.includes as not_available_in_country. style: form explode: false schema: type: array items: type: string enum: [address, establishments, local, vat, signals, legal_events, officers, owners, sanctions] Fields: name: fields in: query required: false description: Comma-separated base fields to keep. id and the requested blocks are always kept. style: form explode: false schema: type: array items: type: string example: [name, status] Limit: name: limit in: query required: false schema: type: integer minimum: 1 maximum: 100 default: 20 After: name: after in: query required: false description: The next cursor of the previous page (in France, the SIRET of the last establishment; in Belgium, its 10-digit establishment unit number). A cursor that does not belong to the company restarts from the first page. schema: type: string MonitorLimit: name: limit in: query required: false schema: type: integer minimum: 1 maximum: 1000 default: 100 NameQuery: name: q in: query required: false description: Company name to search for. Every word of 2 characters or more must appear in the name; the last word is a prefix when it has 3 letters or more. schema: type: string example: peugeot SearchCountry: name: country in: query required: false description: Name search only. Comma-separated country codes; every country is searched when omitted. style: form explode: false schema: type: array items: type: string enum: [FR, BE, CH, GB] example: [FR, BE] SearchStatus: name: status in: query required: false description: Name search only. active keeps active companies only. schema: type: string enum: [active, any] default: any SearchLimit: name: limit in: query required: false description: Name search only. Maximum number of results. schema: type: integer minimum: 1 maximum: 50 default: 20 RegistryId: name: registry_id in: query required: false description: National registry number, without country code. Required when q is not given. schema: type: string example: '552100554' IfNoneMatch: name: If-None-Match in: header required: false description: ETag of a previous response; the API answers 304 without a body when it is unchanged. schema: type: string headers: ETag: description: Identifies this exact response body. schema: type: string RateLimitRemaining: description: Requests left in the current minute. schema: type: integer schemas: Company: type: object required: [siren, diffusion_status, name, created_at, administrative_status, activity_code, legal_category, last_processed_at] properties: siren: type: string diffusion_status: type: string name: type: string nullable: true created_at: type: string nullable: true administrative_status: type: string nullable: true activity_code: type: string nullable: true legal_category: type: string nullable: true last_processed_at: type: string nullable: true Establishment: type: object required: [siret, siren, diffusion_status, name, address, created_at, administrative_status, activity_code, head_office, last_processed_at] properties: siret: type: string siren: type: string diffusion_status: type: string name: type: string nullable: true address: type: string nullable: true created_at: type: string nullable: true administrative_status: type: string nullable: true activity_code: type: string nullable: true head_office: type: boolean last_processed_at: type: string nullable: true Error: type: object required: [error] properties: error: type: string V2Company: type: object description: Base record, identical in every country. Optional blocks appear only when requested. required: [id, country, registry_id, name, status, legal_form, activity, incorporated_on, closed_on, updated_at] properties: id: type: string example: FR-552100554 country: type: string example: FR registry_id: type: string example: '552100554' name: type: string nullable: true status: type: string enum: [active, closed, unknown] legal_form: allOf: - $ref: '#/components/schemas/CodeValue' nullable: true activity: allOf: - $ref: '#/components/schemas/Activity' nullable: true incorporated_on: type: string format: date nullable: true closed_on: type: string format: date nullable: true updated_at: type: string format: date-time nullable: true address: $ref: '#/components/schemas/Address' vat: $ref: '#/components/schemas/VAT' signals: type: array items: $ref: '#/components/schemas/Signal' legal_events: type: array description: Latest 20 announcements, newest first. items: $ref: '#/components/schemas/LegalEvent' owners: type: array description: >- Current persons with significant control (PSC), as published in the UK register. Ceased persons are excluded; addresses and the day of birth are never returned. Empty array when none. Available for the United Kingdom only; in France, Belgium and Switzerland it is reported in meta.includes as not_available_in_country (the French register of beneficial owners is no longer public since 31 July 2024; the Belgian and Swiss registers do not publish them). items: $ref: '#/components/schemas/Owner' sanctions: $ref: '#/components/schemas/Sanctions' establishments: $ref: '#/components/schemas/EstablishmentPage' local: type: object description: >- Fields specific to the country register, as published. Belgium: enterprise_number (0417.497.106), status, juridical_situation (code, label, scheme BE-KBO-JURIDICAL-SITUATION), type_of_enterprise (1 natural person, 2 legal person), juridical_form, start_date, names (language, type legal/abbreviation/commercial, value) and activities (code, nace_version, group, classification MAIN/SECO/ANCI, label). Switzerland: uid (CHE-105.909.036), ehra_id (federal register number), chid (cantonal register number), legal_form (code, label_fr, label_de, label_en), purpose (as registered), municipality (bfs_number, name), canton (two letters), names (language empty for the registered name, else de/fr/it/en/rm, and value), other_registrations (further registered offices of the same legal entity: ehra_id, chid, name, status, municipality, canton, address) and last_listed_on (closed entities only: the last day the register listed it). additionalProperties: true CodeValue: type: object required: [code, label, scheme] properties: code: type: string label: type: string nullable: true scheme: type: string example: FR-INSEE-CJ Activity: type: object required: [nace, code, label, scheme] properties: nace: type: string nullable: true description: NACE rev. 2 class, or null when the national code has no equivalent. example: '70.10' code: type: string example: 70.10Z label: type: string nullable: true scheme: type: string example: FR-NAF-REV2 Address: type: object required: [line, postal_code, city, country, formatted] properties: line: type: string nullable: true postal_code: type: string nullable: true city: type: string nullable: true country: type: string formatted: type: string nullable: true V2Establishment: type: object required: [registry_id, name, head_office, status, activity, opened_on, address] properties: registry_id: type: string description: For France, the 14-digit SIRET; for Belgium, the 10-digit establishment unit number (starting with 2). name: type: string nullable: true head_office: type: boolean status: type: string enum: [active, closed, unknown] activity: allOf: - $ref: '#/components/schemas/Activity' nullable: true opened_on: type: string format: date nullable: true address: allOf: - $ref: '#/components/schemas/Address' nullable: true EstablishmentPage: type: object required: [items, next] properties: items: type: array items: $ref: '#/components/schemas/V2Establishment' next: type: string nullable: true description: Cursor to pass as after; null on the last page. VAT: type: object required: [number, status, checked_at, source] properties: number: type: string example: FR96552100554 status: type: string enum: [pending, valid, invalid, not_verified, unavailable] description: >- pending: check scheduled in the background, retry a few seconds later. valid or invalid: result of the VAT check, reused for 30 days. not_verified: number computed but not checked by this server. unavailable: Switzerland only, the check could not be completed; it is retried later. For a Swiss member of a VAT group, number is the group's (for example CHE-116.281.710 MWST). checked_at: type: string format: date-time nullable: true source: type: string description: Label of the VAT check. example: Vérification TVA Signal: type: object required: [code, since, detail] properties: code: type: string enum: [closed, recently_created, insolvency_proceedings, liquidation, strike_off_proposed, accounts_overdue, confirmation_statement_overdue, dormant] description: >- closed: France, Belgium, Switzerland and the United Kingdom. recently_created and insolvency_proceedings: France, Belgium and the United Kingdom. liquidation (dissolution or liquidation in progress, outside bankruptcy): Belgium, and Switzerland when the registered name carries the mention in Liquidation (en liquidation, in liquidazione). strike_off_proposed, accounts_overdue, confirmation_statement_overdue, dormant: United Kingdom. since: type: string format: date nullable: true detail: type: string nullable: true LegalEvent: type: object required: [id, published_on, family, type, judgment, court, source, url] properties: id: type: string example: A202601892890 published_on: type: string format: date family: type: string enum: [insolvency, conciliation, professional_recovery, deregistration, sale, registration, other] type: type: string enum: [initial, correction, cancellation] judgment: type: object nullable: true properties: family: type: string nullable: true nature: type: string nullable: true date: type: string format: date nullable: true court: type: string nullable: true source: type: string example: Annonces légales FR url: type: string format: uri example: … Owner: type: object description: A current person with significant control, as published in the UK register. required: [kind, name, control, natures_of_control, notified_on, sanctioned] properties: kind: type: string enum: [individual, corporate_entity, legal_person, super_secure] description: >- individual: natural person. corporate_entity: company on a register. legal_person: other legal person. super_secure: person whose details are protected by the register. name: type: string nullable: true description: Name as published; null for super_secure. example: Mr John Smith nationality: type: string description: Individuals only, omitted otherwise. example: British country_of_residence: type: string description: Individuals only, omitted otherwise. example: England birth: type: object description: Individuals only, omitted otherwise. Month and year only, as published; never the day. required: [year, month] properties: year: type: integer example: 1970 month: type: integer minimum: 1 maximum: 12 nullable: true example: 5 control: $ref: '#/components/schemas/OwnerControl' natures_of_control: type: array description: Raw nature-of-control codes, as published. items: type: string example: [ownership-of-shares-50-to-75-percent-as-trust, voting-rights-more-than-25-percent, right-to-appoint-and-remove-directors] notified_on: type: string format: date nullable: true description: Date the control was notified to the register. example: '2016-04-06' identification: $ref: '#/components/schemas/OwnerIdentification' sanctioned: type: boolean description: True when the register marks the person as sanctioned. OwnerControl: type: object required: [shares, voting_rights, appoints_directors, significant_influence, via] properties: shares: allOf: - $ref: '#/components/schemas/PercentRange' nullable: true description: Band of the shares held, in percent, or null. voting_rights: allOf: - $ref: '#/components/schemas/PercentRange' nullable: true description: Band of the voting rights held, in percent, or null. appoints_directors: type: boolean description: Right to appoint or remove a majority of the directors. significant_influence: type: boolean description: Significant influence or control by other means. via: type: array description: firm and/or trust when control is held through one; empty otherwise. items: type: string enum: [firm, trust] PercentRange: type: object required: [min, max] properties: min: type: integer example: 50 max: type: integer example: 75 OwnerIdentification: type: object description: Corporate owners only, omitted otherwise. required: [registration_number, country_registered, legal_form] properties: registration_number: type: string nullable: true example: '00686734' country_registered: type: string nullable: true example: England & Wales legal_form: type: string nullable: true example: Private Limited Company Sanctions: type: object description: >- Screening of the company against the main international and national sanctions lists (European Union, United Nations, France, United Kingdom and United States). Only listed entities are compared, never natural persons. match means the registry number is listed as a registration number of the same country (only the EU list gives countries); possible_match means the company name equals a listed name or alias once case, accents, punctuation and legal forms are ignored. The result is indicative: no_match is not a guarantee and does not replace the customer's own due diligence (KYC/AML). Available for France, Belgium, Switzerland and the United Kingdom. required: [status, matches, lists] properties: status: type: string enum: [no_match, possible_match, match] matches: type: array items: $ref: '#/components/schemas/SanctionsMatch' lists: type: array description: The lists screened against, with their publication date. items: $ref: '#/components/schemas/SanctionsList' SanctionsMatch: type: object required: [list, reference, name, match_type] properties: list: type: string enum: [EU, UN, FR, UK, US] reference: type: string description: Reference of the listed entity in its list. name: type: string description: Main name of the listed entity. match_type: type: string enum: [identifier, name] listed_on: type: string format: date description: Listing date, when the list gives it. programs: type: array items: type: string description: Sanctions regimes as each list names them (EU programme code such as RUS, UN committee such as DPRK, UK regime, US program such as RUSSIA-EO14024, French legal basis). example: [RUSSIA-EO14024] SanctionsList: type: object required: [list, name, published_at, entities] properties: list: type: string enum: [EU, UN, FR, UK, US] name: type: string example: European Union sanctions list published_at: type: string description: Publication date of the list (YYYY-MM-DD), or empty when unknown. entities: type: integer description: Number of listed entities compared. Source: type: object required: [name, license] properties: name: type: string example: Registre officiel FR published_at: type: string license: type: string example: '...' Meta: type: object required: [sources] properties: sources: type: array items: $ref: '#/components/schemas/Source' includes: type: object description: State of each requested block. additionalProperties: type: string enum: [ok, not_available_in_country] BatchRequest: type: object required: [ids] additionalProperties: false properties: ids: type: array minItems: 1 maxItems: 100 items: type: string include: type: array items: type: string enum: [address, establishments, local, vat, signals, legal_events, officers, owners, sanctions] BatchItem: type: object required: [id, data] properties: id: type: string data: allOf: - $ref: '#/components/schemas/V2Company' nullable: true error: type: object required: [code, message] properties: code: type: string message: type: string V2Error: type: object required: [error] properties: error: type: object required: [code, message] properties: code: type: string enum: [invalid_identifier, unknown_include, invalid_parameter, invalid_json, query_too_short, invalid_api_key, ip_not_allowed, not_found, country_not_supported, not_available_in_country, rate_limit_exceeded, data_unavailable, internal_error, server_busy, search_unavailable] message: type: string docs: type: string format: uri Suggestion: type: object description: A light search result from the name index, for autocomplete. required: [id, name, status, postal_code, city, kind] properties: id: type: string example: FR-652014051 name: type: string example: CARREFOUR status: type: string enum: [active, closed, unknown] postal_code: type: string nullable: true example: '91300' city: type: string nullable: true example: MASSY kind: type: string enum: [company, person] description: person for a sole trader. ValidationCheck: type: object required: [code, ok] properties: code: type: string enum: [id_format, siren_key, siret_format, siret_key, siret_exists, siret_active, vat_format, vat_country_supported, identifiers_match, company_exists, company_active, vat_registered] description: >- id_format: the global identifier is well formed for a country served (in Switzerland, with a correct modulo-11 UID check digit). siren_key: the SIREN check digit (Luhn) is correct (France). siret_format: the SIRET has 14 digits. siret_key: the SIRET check digit (Luhn) is correct; La Poste establishments use their own rule. siret_exists: the establishment exists in the register. siret_active: the establishment is active. vat_format: the VAT number is well formed (France: the number computed from the SIREN; Belgium: BE and an enterprise number with a correct check; Switzerland: a UID with a correct check digit, followed by MWST, TVA or IVA). vat_country_supported: the VAT number's country is supported (France, Belgium or Switzerland); false for another country. identifiers_match: every identifier points to the same company. company_exists: the company exists in the register. company_active: the company is active. vat_registered: verification status of the VAT number; valid, pending (the check is not complete yet, retry a few seconds later), not_verified and unavailable pass, invalid fails. ok: type: boolean value: type: string description: The value checked (for company_active and vat_registered, the status found). Validation: type: object required: [valid, checks, company] properties: valid: type: boolean description: true only if every check returned is ok. checks: type: array items: $ref: '#/components/schemas/ValidationCheck' company: allOf: - $ref: '#/components/schemas/V2Company' nullable: true description: Base record with address (and vat when a French VAT number was given); null when the identifiers do not match or the company is not found. Monitor: type: object required: [company_id, created_at, checked_at] properties: company_id: type: string example: FR-552100554 created_at: type: string format: date-time description: When monitoring started. checked_at: type: string format: date-time nullable: true description: Last comparison with the registers; null until the first check. watched: type: object nullable: true description: >- The recorded state the next comparison starts from: in_register, name, status, legal_form, activity, address, signals, signal_details, legal_events (count, null where not served), latest_legal_events, sanctions, sanctions_matches and beneficial_owners (count, null where not served). additionalProperties: true MonitorResult: type: object required: [data] properties: data: type: object required: [company_id, created] properties: company_id: type: string description: Canonical global identifier. example: FR-552100554 created: type: boolean description: true when the company was added by this call. MonitorList: type: object required: [data, next, meta] properties: data: type: array items: $ref: '#/components/schemas/Monitor' next: type: string nullable: true description: Company identifier to pass to after for the next page; null on the last page. meta: type: object required: [count, limit] properties: count: type: integer description: Number of companies monitored by the account. limit: type: integer description: Number of companies the plan may monitor (Free 2, Standard 1,000, Pro 10,000). Event: type: object description: >- A change detected on a monitored company. The content of data depends on type: company.status_changed, company.name_changed, company.address_changed, company.activity_changed and company.legal_form_changed have before and after (after may be null); company.removed_from_register has an empty object; signal.added has code, since and detail; signal.removed has code; legal_event.published has event (a LegalEvent); sanctions.changed has before and after (sanctions statuses), added and removed (matches as LIST:reference) and matches (the current SanctionsMatch items); owner.added and owner.removed (United Kingdom) have kind and name. Monitored signals are insolvency_proceedings, liquidation, strike_off_proposed, accounts_overdue, confirmation_statement_overdue and dormant; closed and recently_created never produce signal events. ping is only sent to webhooks, as a test from the dashboard, with an empty company_id. required: [id, type, company_id, detected_at, data] properties: id: type: string example: evt_42 type: type: string enum: - company.status_changed - company.name_changed - company.address_changed - company.activity_changed - company.legal_form_changed - company.removed_from_register - signal.added - signal.removed - legal_event.published - sanctions.changed - owner.added - owner.removed - ping company_id: type: string example: FR-552100554 detected_at: type: string format: date-time data: anyOf: - $ref: '#/components/schemas/EventFieldChange' - $ref: '#/components/schemas/EventSignalAdded' - $ref: '#/components/schemas/EventSignalRemoved' - $ref: '#/components/schemas/EventLegalEvent' - $ref: '#/components/schemas/EventSanctionsChanged' - $ref: '#/components/schemas/EventOwner' - type: object description: company.removed_from_register (empty) or ping (message). additionalProperties: true example: id: evt_42 type: company.address_changed company_id: FR-552100554 detected_at: '2026-10-03T04:00:00Z' data: before: 75 AV DE LA GRANDE ARMEE 75116 PARIS after: 7 RUE HENRI SAINTE-CLAIRE DEVILLE 92500 RUEIL-MALMAISON EventFieldChange: type: object description: company.status_changed, company.name_changed, company.address_changed, company.activity_changed, company.legal_form_changed. required: [before, after] properties: before: type: string after: type: string nullable: true EventSignalAdded: type: object required: [code, since, detail] properties: code: type: string enum: [insolvency_proceedings, liquidation, strike_off_proposed, accounts_overdue, confirmation_statement_overdue, dormant] since: type: string format: date nullable: true detail: type: string nullable: true EventSignalRemoved: type: object required: [code] properties: code: type: string enum: [insolvency_proceedings, liquidation, strike_off_proposed, accounts_overdue, confirmation_statement_overdue, dormant] EventLegalEvent: type: object required: [event] properties: event: $ref: '#/components/schemas/LegalEvent' EventSanctionsChanged: type: object required: [before, after, added, removed, matches] properties: before: type: string enum: [no_match, possible_match, match] after: type: string enum: [no_match, possible_match, match] added: type: array items: type: string example: ['US:12345'] removed: type: array items: type: string example: [] matches: type: array items: $ref: '#/components/schemas/SanctionsMatch' EventOwner: type: object required: [kind, name] properties: kind: type: string enum: [individual, corporate_entity, legal_person, super_secure] name: type: string nullable: true EventList: type: object required: [data, next] properties: data: type: array items: $ref: '#/components/schemas/Event' next: type: string nullable: true description: Identifier of the last event of the page, to pass to after; null when there is no new event. example: evt_42 responses: BadRequest: description: Invalid SIREN or SIRET content: application/json: schema: $ref: '#/components/schemas/Error' Unauthorized: description: Missing or invalid API key content: application/json: schema: $ref: '#/components/schemas/Error' Forbidden: description: ip_not_allowed (request from an IP address outside the account's allowlist, set in the dashboard on the Pro plan) content: application/json: schema: $ref: '#/components/schemas/Error' NotFound: description: No matching record content: application/json: schema: $ref: '#/components/schemas/Error' TooManyRequests: description: Plan request rate exceeded headers: Retry-After: schema: type: string content: application/json: schema: $ref: '#/components/schemas/Error' Unavailable: description: Service temporarily busy or unavailable content: application/json: schema: $ref: '#/components/schemas/Error' DataUnavailable: description: Stock data could not be read content: application/json: schema: $ref: '#/components/schemas/Error' V2NotModified: description: The response is unchanged since the ETag sent in If-None-Match V2BadRequest: description: invalid_identifier, unknown_include, invalid_parameter or invalid_json content: application/json: schema: $ref: '#/components/schemas/V2Error' V2Unauthorized: description: invalid_api_key content: application/json: schema: $ref: '#/components/schemas/V2Error' V2Forbidden: description: ip_not_allowed (request from an IP address outside the account's allowlist, set in the dashboard on the Pro plan) content: application/json: schema: $ref: '#/components/schemas/V2Error' V2NotFound: description: not_found, country_not_supported or not_available_in_country content: application/json: schema: $ref: '#/components/schemas/V2Error' V2TooManyRequests: description: rate_limit_exceeded headers: Retry-After: schema: type: string content: application/json: schema: $ref: '#/components/schemas/V2Error' V2DataUnavailable: description: data_unavailable content: application/json: schema: $ref: '#/components/schemas/V2Error' V2Busy: description: server_busy headers: Retry-After: schema: type: string content: application/json: schema: $ref: '#/components/schemas/V2Error' V2MonitoringUnavailable: description: monitoring_unavailable (monitoring is not available on this server) content: application/json: schema: $ref: '#/components/schemas/V2Error' x-webhooks: event: post: summary: Event delivered to the account's webhook description: >- Set up in the dashboard (Monitoring section): one HTTPS URL per account, on a public host. Private, loopback and link-local addresses are refused and redirects are not followed. Each event is POSTed with the event object as JSON body. Companies-Signature is t=,v1=." computed with the whsec_ secret shown in the dashboard>. Verify it on the raw body in constant time and reject a t more than 5 minutes away. A 2xx answer within 15 seconds is a success; otherwise the delivery is retried after 1 min, 5 min, 30 min, 2 h, 6 h, 12 h and 24 h, then marked failed (the event stays readable through GET /v2/events). Deliveries may arrive more than once or out of order: deduplicate on the event id. A ping test event can be sent from the dashboard. Deliveries do not count as requests. operationId: eventWebhook security: [] parameters: - name: Companies-Event-Id in: header required: true schema: type: string example: evt_42 - name: Companies-Signature in: header required: true schema: type: string example: t=1791000000,v1=5257a869e7ecebeda32affa62cdca3fa51cad7e77a0e56ff536d0ce8e108d8bd requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/Event' responses: '200': description: Any 2xx answer within 15 seconds acknowledges the delivery.