> ## Documentation Index
> Fetch the complete documentation index at: https://docs.otbstudio.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# The REST API

> Five read-only JSON endpoints for Belgian companies: search, profile, ownership, annual accounts and people. Bearer key, OpenAPI 3.0 specification.

| Route | Needs | Answers |
| - | - | - |
| `GET /v1/companies?q=&limit=` | key | Up to 25 matches |
| `GET /v1/companies/{id}` | key | One profile, or `404` |
| `GET /v1/companies/{id}/ownership` | key | Shareholders and participations |
| `GET /v1/companies/{id}/financials?years=&detail=` | key | The filed figures, one row per period |
| `GET /v1/companies/{id}/people?limit=` | key | Directors and other mandates, current ones first |
| `POST /mcp` | key | The [MCP server](/mcp.md), also at `https://mcp.otbstudio.ai/mcp` |
| `GET /v1/pricing` | none | The live [price list](/pricing.md) |
| `GET /openapi.json` | none | The OpenAPI 3.0 specification. `/openapi.nl.json` and `/openapi.fr.json` are the Dutch and French versions |
| `GET /health` | none | Liveness |

`{id}` is the enterprise number in any usual form: `BE0712345630`, `0712.345.630` or `0712345630`. Every served reply carries `X-Credits-Cost` and `X-Credits-Remaining` ([Limits](/limits.md)). Fields that are empty for a company are left out, never sent as `null`.

There is no pagination: a reply holds at most the route's `limit`. There is no official SDK; the [OpenAPI specification](https://api.otbstudio.ai/openapi.json) is the contract, and you can generate a client from it.

The version is in the path, `/v1/`. Within it, changes only add a route, a parameter or a field, so write clients that ignore fields they do not know.

## Search

```bash theme={null}
curl -s "https://api.otbstudio.ai/v1/companies?q=noordkaap&limit=2" \
  -H "Authorization: Bearer $OTB_KEY"
```

> **Example response**
>
> ```json theme={null}
> {
>   "companies": [
>     { "enterpriseNumber": "BE0734567835", "name": "Noordkaap Warehousing", "employees": 214, "statusCode": "AC" },
>     { "enterpriseNumber": "BE0712345630", "name": "Noordkaap Logistics", "employees": 187, "statusCode": "AC" }
>   ]
> }
> ```

`limit` is never refused: a missing or out-of-range value (below 1 or above 25) becomes the default of 10. `q` is required: without it the reply is `400 query_required`. Matching is on whole words and does not correct typos. Companies flagged `deleted` are left out of search, but can still be fetched by number. Search costs no credits.

`name` is the name that matched. `employees` here is the register's own figure and can differ from the profile's `financials.employees`, which comes from the latest filing.

## Profile

```bash theme={null}
curl -s "https://api.otbstudio.ai/v1/companies/0712.345.630" \
  -H "Authorization: Bearer $OTB_KEY"
```

> **Example response**
>
> ```json theme={null}
> {
>   "enterpriseNumber": "BE0712345630",
>   "nameNl": "Noordkaap Logistics",
>   "statusCode": "AC",
>   "juridicalFormCode": "014",
>   "juridicalSituationCode": "000",
>   "typeOfEnterpriseCode": "2",
>   "deleted": false,
>   "startDate": "1998-06-15",
>   "street": "Kaaiweg 14",
>   "zipCode": "9000",
>   "city": "Gent",
>   "website": "noordkaap.example",
>   "activities": "MAIN :: 006 :: 2025 :: 49410;MAIN :: 001 :: 2025 :: 52100",
>   "financials": {
>     "closingDate": "2025-03-31",
>     "reference": "2025-00184417",
>     "schemaType": "full",
>     "employees": 186.4,
>     "equity": 12480310.52,
>     "operatingIncome": 3912774.18,
>     "ebitda": 5240118.66,
>     "resultForPeriod": 2731905.07,
>     "healthIndicator": 10
>   },
>   "has": {
>     "annualAccounts": true,
>     "participations": true,
>     "accountants": true,
>     "valuations": false,
>     "socialBalances": true
>   },
>   "snapshotDate": "2026-04-29"
> }
> ```

`financials` is the newest filing. It is the same record the financials route returns first, so the two cannot disagree.

## Ownership

```bash theme={null}
curl -s "https://api.otbstudio.ai/v1/companies/BE0712345630/ownership" \
  -H "Authorization: Bearer $OTB_KEY"
```

> **Example response**
>
> ```json theme={null}
> {
>   "enterpriseNumber": "BE0712345630",
>   "shareholders": [
>     {
>       "name": "Noordkaap Holding NV",
>       "enterpriseNumber": "BE0723456781",
>       "stakePercent": 72.5,
>       "shareClass": "Gewone aandelen",
>       "asOf": "2025-03-31",
>       "sourceReference": "2025-00184417",
>       "sourceSystem": "NBB",
>       "exact": true
>     }
>   ],
>   "participations": [
>     {
>       "name": "Noordkaap Warehousing",
>       "enterpriseNumber": "BE0734567835",
>       "stakePercent": 100,
>       "asOf": "2025-03-31",
>       "sourceReference": "2025-00184417",
>       "sourceSystem": "NBB",
>       "exact": true
>     }
>   ]
> }
> ```

Both directions use one shape. `shareholders` hold a stake in this company; `participations` are the stakes it holds in others. Every `enterpriseNumber` goes straight back into this route, so a chain can be walked. Either list can be empty.

## Financials

```bash theme={null}
curl -s "https://api.otbstudio.ai/v1/companies/BE0712345630/financials?years=1&detail=true" \
  -H "Authorization: Bearer $OTB_KEY"
```

> **Example response**
>
> ```json theme={null}
> {
>   "periods": [
>     {
>       "closingDate": "2025-03-31",
>       "reference": "2025-00184417",
>       "schemaType": "full",
>       "employees": 186.4,
>       "equity": 12480310.52,
>       "operatingIncome": 3912774.18,
>       "ebitda": 5240118.66,
>       "resultForPeriod": 2731905.07,
>       "healthIndicator": 10,
>       "cashFlow": {
>         "operating": 4410228.35,
>         "investing": -1876340.12,
>         "financing": -1504377.8,
>         "free": 2533888.23,
>         "cashAtPeriodEnd": 1388902.41,
>         "distributionsToOwners": 600000
>       },
>       "balanceSheet": {
>         "operatingProfit": 3480112.9,
>         "depreciation": 1328006.48,
>         "staffCosts": 9876540.21,
>         "totalAssets": 31902554.7,
>         "totalDebt": 8044120.33,
>         "interestPaid": 288410.12
>       }
>     }
>   ]
> }
> ```

One row per accounting period, newest first. `years` is 1 to 20; a missing or out-of-range value becomes the default of 10. Without `detail=true` each row has the six headline figures only. Each period is charged, so ten years cost about ten times one.

## People

```bash theme={null}
curl -s "https://api.otbstudio.ai/v1/companies/BE0712345630/people?limit=2" \
  -H "Authorization: Bearer $OTB_KEY"
```

> **Example response**
>
> ```json theme={null}
> {
>   "people": [
>     {
>       "lastName": "Verhaegen",
>       "firstName": "Lotte",
>       "category": "ADMINISTER",
>       "role": "13",
>       "profession": "Gedelegeerd bestuurder",
>       "startDate": "2024-09-25",
>       "endDate": "2028-09-27",
>       "current": true,
>       "viaCompany": "Verhaegen Consult BV",
>       "viaEnterpriseNumber": "BE1023456797",
>       "sourceSystem": "NBB",
>       "sourceReference": "2025-00184417"
>     },
>     {
>       "lastName": "Peeters",
>       "firstName": "Luc",
>       "category": "OTHERMANDATE",
>       "role": "Aankoper",
>       "current": true,
>       "sourceSystem": "BSDM"
>     }
>   ]
> }
> ```
>
> Names in this example are fictitious.

Current mandates first, then the history. `limit` is 1 to 200; a missing or out-of-range value becomes the default of 50. Mandates beyond the first 200 cannot be retrieved. Political party, remuneration and home addresses are never returned, and people the source marks as hidden are left out.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.