{
  "openapi": "3.2.0",
  "$self": "https://companyregistryapi.com/api/openapi.json",
  "info": {
    "title": "CompanyRegistryAPI.com free API",
    "summary": "Free JSON API for company search and company profiles, powered by Coragrid.",
    "description": "Three read-only endpoints mirror the companyregistryapi.com website: a prefix search over company names and business IDs, one company by its permanent ID, and that company's current officers with their sources. Responses use the same permanent IDs and field names as the Coragrid public API (https://api.coragrid.com/openapi.json), so moving to a Coragrid credential later needs no data migration.\n\nNo key is required. Requests are rate limited per client address; over the limit the API answers 429 with a Retry-After header, and https://companyregistryapi.com/api states the current allowance. Browser requests from any origin are allowed for GET. Errors are RFC 9457 problem documents with a stable code. Show \"Powered by Coragrid\" wherever you display the data.",
    "termsOfService": "https://companyregistryapi.com/about",
    "contact": {
      "name": "CompanyRegistryAPI.com",
      "url": "https://companyregistryapi.com/api"
    },
    "version": "1.0.0"
  },
  "servers": [
    {
      "url": "https://api.companyregistryapi.com",
      "name": "production",
      "description": "The free API. Every path appends to this URL."
    }
  ],
  "security": [],
  "tags": [
    {
      "name": "Companies",
      "description": "Company search, profiles and current officers"
    }
  ],
  "paths": {
    "/v1/search": {
      "get": {
        "operationId": "searchCompanies",
        "summary": "Search companies by the start of a name or a business ID",
        "description": "Matches the start of a company name or a business ID, in registry name order with no relevance score. Results carry the profile fields but no identifiers; read the company for those. Pages continue through next_cursor.",
        "tags": ["Companies"],
        "parameters": [
          { "$ref": "#/components/parameters/Query" },
          { "$ref": "#/components/parameters/Country" },
          { "$ref": "#/components/parameters/Limit" },
          { "$ref": "#/components/parameters/Cursor" }
        ],
        "responses": {
          "200": {
            "description": "One page of matching companies.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/SearchPage" },
                "example": {
                  "object": "list",
                  "query": "example",
                  "countries": ["FI"],
                  "data": [
                    {
                      "id": "co_014d2pf2dbsqqg28t5cy4tqkff",
                      "object": "company",
                      "lifecycle": { "status": "active" },
                      "name": "Example Robotics Oy",
                      "country_code": "FI",
                      "company_status": "active",
                      "company_type": "private_limited_company"
                    }
                  ],
                  "next_cursor": null,
                  "attribution": "Powered by Coragrid"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidRequest" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "$ref": "#/components/responses/UpstreamError" },
          "503": { "$ref": "#/components/responses/UpstreamUnavailable" }
        }
      }
    },
    "/v1/companies/{company_id}": {
      "get": {
        "operationId": "getCompany",
        "summary": "One company by permanent ID",
        "description": "Redirected records return the requested handle with the canonical ID in lifecycle.canonical_id; split records list lifecycle.successor_ids. Unknown and restricted values are absent, never filled in.",
        "tags": ["Companies"],
        "parameters": [{ "$ref": "#/components/parameters/CompanyId" }],
        "responses": {
          "200": {
            "description": "The company.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/CompanyEnvelope" },
                "example": {
                  "data": {
                    "id": "co_014d2pf2dbsqqg28t5cy4tqkff",
                    "object": "company",
                    "lifecycle": { "status": "active" },
                    "name": "Example Robotics Oy",
                    "summary": "Finnish industrial robotics for flexible manufacturing cells.",
                    "country_code": "FI",
                    "company_status": "active",
                    "company_type": "private_limited_company",
                    "legal_form": "Osakeyhtiö",
                    "as_of_date": "2026-07-15",
                    "identifiers": [
                      {
                        "scheme": "national_registry_number",
                        "value": "1234567-8",
                        "country_scope": "FI"
                      }
                    ]
                  },
                  "attribution": "Powered by Coragrid"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidRequest" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "$ref": "#/components/responses/UpstreamError" },
          "503": { "$ref": "#/components/responses/UpstreamUnavailable" }
        }
      }
    },
    "/v1/companies/{company_id}/officers": {
      "get": {
        "operationId": "listCompanyOfficers",
        "summary": "Current officers of one company, with their sources",
        "description": "Each officer names the publishing system, its URL when known and the observation time. A redirected company ID resolves to its canonical record; both IDs are returned.",
        "tags": ["Companies"],
        "parameters": [{ "$ref": "#/components/parameters/CompanyId" }],
        "responses": {
          "200": {
            "description": "The current officers.",
            "content": {
              "application/json": {
                "schema": { "$ref": "#/components/schemas/OfficerPage" },
                "example": {
                  "object": "company_officer_list",
                  "requested_company_id": "co_014d2pf2dbsqqg28t5cy4tqkff",
                  "company_id": "co_014d2pf2dbsqqg28t5cy4tqkff",
                  "data": [
                    {
                      "object": "company_officer",
                      "name": "Anna Virtanen",
                      "roles": ["Chief executive officer"],
                      "appointed_on": "2024-01-15",
                      "source": {
                        "system": "official_company_register",
                        "url": "https://registry.example/officers/anna-virtanen",
                        "title": "Current officers",
                        "published_at": "2026-07-14T09:30:00Z",
                        "observed_at": "2026-07-15T07:00:00Z"
                      }
                    }
                  ],
                  "has_more": false,
                  "attribution": "Powered by Coragrid"
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/InvalidRequest" },
          "404": { "$ref": "#/components/responses/NotFound" },
          "429": { "$ref": "#/components/responses/RateLimited" },
          "502": { "$ref": "#/components/responses/UpstreamError" },
          "503": { "$ref": "#/components/responses/UpstreamUnavailable" }
        }
      }
    }
  },
  "components": {
    "parameters": {
      "Query": {
        "name": "q",
        "in": "query",
        "required": true,
        "description": "The start of a company name or a business ID, 3 to 64 characters once whitespace is collapsed.",
        "schema": {
          "type": "string",
          "minLength": 3,
          "maxLength": 64,
          "example": "example"
        }
      },
      "Country": {
        "name": "country",
        "in": "query",
        "description": "ISO 3166-1 alpha-2 code of the company's country, such as FI, in either case. Omit it or pass all for every country.",
        "schema": {
          "type": "string",
          "pattern": "^([A-Za-z]{2}|[Aa][Ll][Ll])$",
          "example": "FI"
        }
      },
      "Limit": {
        "name": "limit",
        "in": "query",
        "description": "Results per page.",
        "schema": {
          "type": "integer",
          "minimum": 1,
          "maximum": 25,
          "default": 10
        }
      },
      "Cursor": {
        "name": "cursor",
        "in": "query",
        "description": "The next_cursor value of the previous page. Cursors expire; on 400 start again from the first page.",
        "schema": { "type": "string" }
      },
      "CompanyId": {
        "name": "company_id",
        "in": "path",
        "required": true,
        "description": "A permanent Coragrid company ID.",
        "schema": { "$ref": "#/components/schemas/CompanyId" }
      }
    },
    "headers": {
      "RetryAfter": {
        "description": "Seconds to wait before retrying.",
        "schema": { "type": "integer", "minimum": 1 }
      }
    },
    "responses": {
      "InvalidRequest": {
        "description": "A parameter is missing or malformed, or a cursor has expired; detail names it.",
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/Problem" },
            "example": {
              "type": "https://companyregistryapi.com/problems/invalid-request",
              "title": "Invalid request",
              "status": 400,
              "detail": "Type at least 3 characters of a company name or a business ID.",
              "instance": "https://api.companyregistryapi.com/v1/search",
              "request_id": "req_014d2pf2dbsqqg28t5cy4tqkff",
              "code": "invalid_request",
              "retryable": false
            }
          }
        }
      },
      "NotFound": {
        "description": "No company is visible under that ID.",
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/Problem" },
            "example": {
              "type": "https://companyregistryapi.com/problems/not-found",
              "title": "Resource not found",
              "status": 404,
              "detail": "No company is visible under that ID.",
              "instance": "https://api.companyregistryapi.com/v1/companies/co_00000000000000000000000009",
              "request_id": "req_014d2pf2dbsqqg28t5cy4tqkff",
              "code": "not_found",
              "retryable": false
            }
          }
        }
      },
      "RateLimited": {
        "description": "Over the per-client rate limit; retry after the number of seconds in Retry-After.",
        "headers": {
          "Retry-After": { "$ref": "#/components/headers/RetryAfter" }
        },
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/Problem" },
            "example": {
              "type": "https://companyregistryapi.com/problems/rate-limited",
              "title": "Too many requests",
              "status": 429,
              "detail": "The free API allows a bounded number of requests per minute per client; retry after 1 seconds.",
              "instance": "https://api.companyregistryapi.com/v1/search",
              "request_id": "req_014d2pf2dbsqqg28t5cy4tqkff",
              "code": "rate_limited",
              "retryable": true
            }
          }
        }
      },
      "UpstreamError": {
        "description": "The company data service rejected the request; retryable.",
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/Problem" },
            "example": {
              "type": "https://companyregistryapi.com/problems/upstream-error",
              "title": "Upstream data service error",
              "status": 502,
              "detail": "The company data service rejected the request.",
              "instance": "https://api.companyregistryapi.com/v1/search",
              "request_id": "req_014d2pf2dbsqqg28t5cy4tqkff",
              "code": "upstream_error",
              "retryable": true
            }
          }
        }
      },
      "UpstreamUnavailable": {
        "description": "Company data is temporarily unavailable (upstream_unavailable) or the company data service is busy (upstream_busy, with Retry-After); retryable.",
        "headers": {
          "Retry-After": { "$ref": "#/components/headers/RetryAfter" }
        },
        "content": {
          "application/problem+json": {
            "schema": { "$ref": "#/components/schemas/Problem" },
            "example": {
              "type": "https://companyregistryapi.com/problems/upstream-busy",
              "title": "Company data temporarily unavailable",
              "status": 503,
              "detail": "The company data service is busy; retry shortly.",
              "instance": "https://api.companyregistryapi.com/v1/search",
              "request_id": "req_014d2pf2dbsqqg28t5cy4tqkff",
              "code": "upstream_busy",
              "retryable": true
            }
          }
        }
      }
    },
    "schemas": {
      "CompanyId": {
        "type": "string",
        "description": "A permanent Coragrid company ID. Names and registry numbers change and repeat; the ID does not.",
        "pattern": "^co_[0-7][0-9a-hj-km-np-tv-z]{25}$",
        "example": "co_014d2pf2dbsqqg28t5cy4tqkff"
      },
      "CompanyLifecycle": {
        "type": "object",
        "description": "Whether the record is current. A redirected record names its canonical record; a split record names its successors.",
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "active",
              "redirected",
              "split",
              "tombstoned",
              "restricted"
            ]
          },
          "canonical_id": {
            "$ref": "#/components/schemas/CompanyId",
            "description": "The current record of a redirected one."
          },
          "successor_ids": {
            "type": "array",
            "description": "The records a split one continues as.",
            "items": { "$ref": "#/components/schemas/CompanyId" }
          }
        },
        "required": ["status"]
      },
      "CompanyIdentifier": {
        "type": "object",
        "properties": {
          "scheme": {
            "type": "string",
            "description": "Canonical scheme as the API returns it: national_registry_number, lei, eu_vat_number, vat_number or tin. A Finnish business ID is national_registry_number scoped to FI.",
            "example": "national_registry_number"
          },
          "value": {
            "type": "string",
            "description": "The identifier as the register publishes it.",
            "example": "1234567-8"
          },
          "country_scope": {
            "type": "string",
            "description": "Registration jurisdiction that scopes the value, ISO 3166-1 alpha-2 or ISO 3166-2. Absent for globally unique schemes such as lei.",
            "example": "FI"
          }
        },
        "required": ["scheme", "value"]
      },
      "CompanyClassification": {
        "type": "object",
        "description": "A current activity classification in its source scheme and version. Codes preserve source punctuation and leading zeros; no crosswalk is inferred.",
        "properties": {
          "scheme": { "type": "string", "example": "nace_2008" },
          "code": { "type": "string", "example": "28.99" },
          "label": { "type": "string" },
          "is_primary": { "type": "boolean" }
        },
        "required": ["scheme", "code", "is_primary"]
      },
      "Company": {
        "type": "object",
        "description": "A company as the registers describe it. Fields the registers do not publish are absent.",
        "properties": {
          "id": { "$ref": "#/components/schemas/CompanyId" },
          "object": { "type": "string", "const": "company" },
          "lifecycle": { "$ref": "#/components/schemas/CompanyLifecycle" },
          "name": { "type": "string" },
          "summary": { "type": "string" },
          "country_code": {
            "type": "string",
            "description": "Profile country: the headquarters address country as ISO 3166-1 alpha-2. The registration jurisdiction is the country_scope of the first scoped entry in identifiers; the two can differ.",
            "example": "FI"
          },
          "company_status": { "type": "string", "example": "active" },
          "company_type": {
            "type": "string",
            "example": "private_limited_company"
          },
          "legal_form": {
            "type": "string",
            "description": "The legal form exactly as the register publishes it, in the register's language, such as Osakeyhtiö or Canada Business Corporations Act; a few registers publish a code. company_type is the register's own type code or label, so its values differ per register.",
            "example": "Osakeyhtiö"
          },
          "industry": { "type": "string" },
          "business_model": { "type": "string" },
          "product_category": { "type": "string" },
          "operating_geography": { "type": "string" },
          "as_of_date": {
            "type": "string",
            "format": "date",
            "description": "When the register was last observed."
          },
          "classifications": {
            "type": "array",
            "description": "Current activity classifications, primary first, then scheme and code. Absent when none are available. Schemes are not limited to a fixed list.",
            "items": { "$ref": "#/components/schemas/CompanyClassification" }
          },
          "identifiers": {
            "type": "array",
            "description": "Current registry identifiers, strongest first: national registry number, LEI, EU VAT number, VAT number, TIN. The first entry with a country_scope names the registration jurisdiction. On the company resource only, never on search results.",
            "items": { "$ref": "#/components/schemas/CompanyIdentifier" }
          }
        },
        "required": ["id", "object", "lifecycle"]
      },
      "SearchPage": {
        "type": "object",
        "properties": {
          "object": { "type": "string", "const": "list" },
          "query": {
            "type": "string",
            "description": "The query as searched, with whitespace collapsed."
          },
          "countries": {
            "type": "array",
            "description": "The country filter in effect; empty when every country was searched.",
            "items": { "type": "string", "example": "FI" }
          },
          "data": {
            "type": "array",
            "description": "Matching companies in registry name order, without identifiers or relevance scores.",
            "items": { "$ref": "#/components/schemas/Company" }
          },
          "next_cursor": {
            "type": ["string", "null"],
            "description": "Pass as cursor for the next page; null on the last page."
          },
          "attribution": {
            "type": "string",
            "const": "Powered by Coragrid"
          }
        },
        "required": [
          "object",
          "query",
          "countries",
          "data",
          "next_cursor",
          "attribution"
        ]
      },
      "CompanyEnvelope": {
        "type": "object",
        "properties": {
          "data": { "$ref": "#/components/schemas/Company" },
          "attribution": {
            "type": "string",
            "const": "Powered by Coragrid"
          }
        },
        "required": ["data", "attribution"]
      },
      "OfficerSource": {
        "type": "object",
        "description": "Where the officer record was published and when it was observed.",
        "properties": {
          "system": {
            "type": "string",
            "description": "The publishing system.",
            "example": "official_company_register"
          },
          "url": { "type": "string", "format": "uri" },
          "title": { "type": "string" },
          "published_at": { "type": "string", "format": "date-time" },
          "observed_at": { "type": "string", "format": "date-time" }
        },
        "required": ["system"]
      },
      "Officer": {
        "type": "object",
        "properties": {
          "object": { "type": "string", "const": "company_officer" },
          "name": { "type": "string" },
          "roles": {
            "type": "array",
            "description": "Role titles as the register states them; absent when it states none.",
            "items": { "type": "string" }
          },
          "appointed_on": { "type": "string", "format": "date" },
          "resigned_on": { "type": "string", "format": "date" },
          "source": { "$ref": "#/components/schemas/OfficerSource" }
        },
        "required": ["object", "name", "source"]
      },
      "OfficerPage": {
        "type": "object",
        "properties": {
          "object": { "type": "string", "const": "company_officer_list" },
          "requested_company_id": {
            "$ref": "#/components/schemas/CompanyId",
            "description": "The ID in the request, kept when it redirects to another."
          },
          "company_id": {
            "$ref": "#/components/schemas/CompanyId",
            "description": "The canonical company whose officers these are."
          },
          "data": {
            "type": "array",
            "items": { "$ref": "#/components/schemas/Officer" }
          },
          "has_more": {
            "type": "boolean",
            "description": "Whether the register lists more current officers than returned."
          },
          "attribution": {
            "type": "string",
            "const": "Powered by Coragrid"
          }
        },
        "required": [
          "object",
          "requested_company_id",
          "company_id",
          "data",
          "has_more",
          "attribution"
        ]
      },
      "Problem": {
        "type": "object",
        "description": "An RFC 9457 problem document with the same fields as Coragrid's. Request IDs are the site's own.",
        "properties": {
          "type": {
            "type": "string",
            "format": "uri",
            "description": "https://companyregistryapi.com/problems/ followed by the code with hyphens."
          },
          "title": { "type": "string" },
          "status": { "type": "integer", "minimum": 400, "maximum": 599 },
          "detail": { "type": "string" },
          "instance": {
            "type": "string",
            "format": "uri",
            "description": "The absolute public URL of the request."
          },
          "request_id": {
            "type": "string",
            "pattern": "^req_[0-7][0-9a-hj-km-np-tv-z]{25}$"
          },
          "code": {
            "type": "string",
            "enum": [
              "invalid_request",
              "not_found",
              "rate_limited",
              "upstream_error",
              "upstream_busy",
              "upstream_unavailable"
            ]
          },
          "retryable": {
            "type": "boolean",
            "description": "Whether the same request may succeed later."
          }
        },
        "required": [
          "type",
          "title",
          "status",
          "detail",
          "instance",
          "request_id",
          "code",
          "retryable"
        ]
      }
    }
  }
}
