Skip to content
Subsido

Using the API

Rate limits and quotas

Three limits, each reported before you hit it: requests per second, requests per month, and match evaluations per month.

Per plan

What each plan includes
DeveloperProBusinessEnterprise
Requests per month10,000100,000500,000Unlimited
Match evaluations per monthOne company evaluated against every measure.1001,00010,000Unlimited
Requests per second51540150
API keys23550
Rows per page100200200500
Companies per bulk matchNot includedNot included5005,000
Companies on watchlistsNot includedNot included5,000Unlimited
Webhook endpointsNot included51050
Change feedGET /v1/changesIncludedIncludedIncludedIncluded
Versions of every measureGET /v1/subsidies/{id}/versionsNot includedIncludedIncludedIncluded
A measure as it stood on a date?as_of=Not includedIncludedIncludedIncluded
WebhooksNot includedIncludedIncludedIncluded
Bulk matchingPOST /v1/match/bulkNot includedNot includedIncludedIncluded
WatchlistsNot includedNot includedIncludedIncluded
Whole-catalogue exportNDJSONNot includedNot includedIncludedIncluded
Redistribution rights (by contract)Not includedNot includedNot includedIncluded

Rendered from GET /v1/plans, the table the API enforces. Prices are on pricing.

An account without a plan can create a key, but that key answers 402 subscription_required on every route, before any limit is counted, until a plan is chosen in the dashboard.

Requests per second

Each account has a token bucket sized for its plan, shared by all its keys, with a burst of one second’s allowance: a handful of parallel requests followed by a pause is fine, a hot loop is not. Over it, the answer is 429 rate_limit_exceeded with Retry-After: 1. The rate limit is checked before the quota, so a client in a hot loop is told to slow down rather than that its month is spent. The routes that need no key are limited per client address instead.

Requests per month

Every request to a keyed route counts once, whatever it returns, the MCP endpoint and GET /v1/key included; a request without a valid key or without a plan, or refused by the rate limit or the quota itself, does not. Live and test keys count alike. The month is the UTC calendar month. When it is spent, the answer is 429 quota_exceeded with Retry-After set to the seconds until the next month begins. Enterprise has no monthly limit.

Match evaluations

Matching has its own monthly allowance, counted apart from requests. A match evaluation is one company evaluated against every measure:

CallEvaluations
POST /v1/match1
POST /v1/match/bulkOne per company with valid facts; a company answered with its own error is not counted.
POST /v1/watchlists/{id}/companiesOne per company accepted, added or replaced.
MCP match_company, explain_eligibility1 each.
Re-evaluating a watchlist when a measure changesNothing. Included in the plan.

When the allowance is spent, matching answers 429 match_quota_exceeded (with details.limit and Retry-After), and everything else keeps working: you can still search and read measures. A bulk request or a watchlist upload that would go past the allowance is refused as a whole, and nothing of it is evaluated or counted. GET /v1/key reports match_evaluations_this_month.

Headers

Every response from a keyed route carries the monthly figures:

HeaderMeaning
RateLimit-LimitYour plan’s monthly request quota.
RateLimit-RemainingRequests left this month, after this one. It reaches 0 on the last request you are allowed.
RateLimit-ResetSeconds until the quota resets, at the start of the next UTC month.
X-Quota-Limit, X-Quota-RemainingThe same two figures under a second name.
curl -sI "https://api.subsido.be/v1/subsidies?limit=1" -H "Authorization: Bearer sb_live_..." | grep -i -E "ratelimit|quota"
  • An unlimited plan sends no -Limit or -Remaining header rather than a very large number; RateLimit-Reset is still sent.
  • The headers describe the monthly request quota, not the per-second limit and not match evaluations.
  • Browsers can read them: the API exposes them to cross-origin JavaScript.

Other ceilings

Per request

WhatLimit
Rows per pageThe plan’s max_page_size. See pagination.
Matches returned by POST /v1/matchlimit, 1 to 100 (default 25).
Companies in POST /v1/match/bulkThe plan’s max_bulk_companies; above it, plan_required naming the plan that allows it.
Companies in one watchlist upload1,000.
Search text q200 characters.
Bulk export downloadsTwo at a time across the service; a third waits (429, Retry-After: 5).

Per account

WhatLimit
API keysThe plan’s api_keys.
Watchlists50.
Companies across all watchlistsThe plan’s watchlist_companies.
Webhook endpointsThe plan’s webhook_endpoints.

Need more?

A larger plan is one click in the dashboard. If what you need does not fit any plan, write to us: Enterprise is sized to the use.