Start
Authentication
Bearer keys, live and test keys, the routes that answer without one, and checking a key.
Bearer keys
Send your key on every request to a keyed route, as a bearer token in the Authorization header.
curl "https://api.subsido.be/v1/subsidies?limit=3" \ -H "Authorization: Bearer sb_live_..."X-API-Key: sb_live_...works too, for tools that cannot set anAuthorizationheader. When both are sent,Authorizationwins.- The scheme is case-insensitive (
Bearerorbearer), and a key sent inAuthorizationwithout the scheme is accepted as well. - A missing, malformed or revoked key is
401 unauthorized. The response does not say which of the three, so that someone guessing keys learns nothing from it. - A valid key on an account without a plan is
402 subscription_requireduntil a plan is chosen. - The MCP endpoint,
POST /mcp, takes the same key in the same header.
Live and test keys
A key is minted as sb_live_… or sb_test_…. Both reach exactly the same data and both are metered the same way, against your monthly quota, your match evaluations and your rate limit. The label is yours: use test keys for CI and local development so their usage is told apart from production’s in the dashboard.
The number of keys an account may hold depends on the plan (see pricing). A key is shown once, when it is created. Only its SHA-256 hash and its first characters are stored, so there is no endpoint that can return a secret: a lost key is revoked in the dashboard and replaced. Revoking takes effect immediately.
Keep keys on the server
Checking a key
GET /v1/key answers with the calling key’s plan, everything the plan allows, and this month’s usage, the request being made included. It is the right first request for a new integration and a good health check for a running one. Like every other route, the answer is wrapped in data, with meta beside it.
curl "https://api.subsido.be/v1/key" -H "Authorization: Bearer sb_live_..."{
"data": {
"live": true,
"plan": {
"plan": "developer",
"label": "Developer",
"price_monthly_eur": 20,
"price_yearly_eur": 200,
"price_from_monthly_eur": null,
"self_serve": true,
"purchasable": true,
"monthly_requests": 10000,
"monthly_match_evaluations": 100,
"rate_limit_rps": 5,
"api_keys": 2,
"max_page_size": 100,
"max_bulk_companies": 0,
"watchlist_companies": 0,
"webhook_endpoints": 0,
"capabilities": {
"change_feed": true,
"history": false,
"as_of": false,
"webhooks": false,
"bulk_match": false,
"watchlists": false,
"bulk_export": false,
"redistribution_rights": false
}
},
"requests_this_month": 1284,
"match_evaluations_this_month": 37
},
"meta": {
"request_id": "req_01hxyz",
"warnings": []
}
}Routes that need no key
These publish what the website prints anyway. They are rate limited per client address, carry no RateLimit-* headers, and do not count against any quota.
| Route | What it is for |
|---|---|
| GET /v1/health | Status, version, and which sources are not fresh. |
| GET /v1/plans | Plans, prices and everything each allows. |
| GET /v1/openapi.json | The OpenAPI 3.1 contract. |
| GET /v1/taxonomy | Every closed vocabulary with Dutch, French and English labels, the rule fields and operators, the event types. |
| GET /v1/coverage | How many measures there are, by status, source, instrument, level, region and topic. |
| GET /v1/sources | Every source, its licence and rights mode, and its freshness. |
| GET /v1/sources/{id} | One source, with its last ten ingestion runs. |
Everything else, the MCP endpoint included, needs a key. A route that needs one answers 401 without it; see errors.
Headers on every response
| Header | Meaning |
|---|---|
| X-Request-Id | The request’s id (req_…), also in meta.request_id or error.request_id. Quote it when you write to us. |
| X-Independence | The independence statement: an independent service, not a public authority. Machines can read it without reading the website. |
| RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset | On keyed routes: your monthly request quota, what is left, and the seconds until it resets. See rate limits. |
| X-Quota-Limit, X-Quota-Remaining | The same monthly figures under a second name. |
