Matching
Watchlists
An accountant with three thousand clients should not have to search. Put the companies on a watchlist once; they are matched at once, and re-evaluated whenever a measure changes, with an event for every match that appears, changes or goes.
Business and aboveWatchlists need the watchlists capability. Up to 50 watchlists per account; the companies across all of them are capped by plan (5,000 on Business, unlimited on Enterprise).
Create a watchlist
curl -X POST "https://api.subsido.be/v1/watchlists" \ -H "Authorization: Bearer sb_live_..." \ -H "Content-Type: application/json" \ -d '{"name": "Clients Gent", "language": "nl", "options": {"statuses": ["open", "continuous", "forthcoming"]}}'| Property | Meaning |
|---|---|
| name | 1 to 120 characters. |
| options | The same match options as POST /v1/match: statuses, instrument_types, include_not_eligible, include_unrelated. Applied to every company on the list. |
| language | nl, fr or en (default): the language of stored labels and questions. |
201 with the watchlist: { id, name, options, language, companies, matches, created_at, updated_at, last_evaluated_at }, where id is wl_…, companies counts the companies on it and matches the current matches that are not not_eligible.
| Route | What it does |
|---|---|
| GET /v1/watchlists | Every watchlist of the account, in one page. |
| GET /v1/watchlists/{id} | One watchlist. |
| PATCH /v1/watchlists/{id} | Change name, options or language; send only what changes. |
| DELETE /v1/watchlists/{id} | Delete it, with its companies and their matches. |
| POST /v1/watchlists/{id}/companies | Add or replace companies, and evaluate them now. |
| GET /v1/watchlists/{id}/companies | The companies on it, paged with limit and cursor. |
| DELETE /v1/watchlists/{id}/companies/{reference} | Remove one company (URL-encode the reference). |
| GET /v1/watchlists/{id}/matches | The current matches. |
Add companies
curl -X POST "https://api.subsido.be/v1/watchlists/wl_06f8r9t2b4c6d8e0f2g4h6j8km/companies" \ -H "Authorization: Bearer sb_live_..." \ -H "Content-Type: application/json" \ -d '{"companies": [ {"reference": "client-0042", "company": {"postcode": "9000", "employees": 12, "turnover_eur": 1500000, "legal_form": "bv", "nace": ["62.010"]}}, {"reference": "client-0043", "company": {"postcode": "98200", "legal_form": "eenmanszaak"}, "project": {"topics": ["energy_efficiency"]}} ]}'- 1 to 1,000 companies per request. Each has your own
reference(1 to 200 characters), andcompanyandprojecttake exactly the properties of a match request. - A reference already on the watchlist is replaced, and does not count again against the plan’s company cap.
- A company with invalid facts, a duplicate or an empty reference is rejected on its own; the rest are accepted.
- Every accepted company is evaluated before the call returns, against the same measures as
/v1/match, and counts as one match evaluation. The request is refused as a whole withmatch_quota_exceededwhen the accepted companies would take you past your allowance, and withplan_requiredwhen they would take the account past its company cap.
{
"watchlist_id": "wl_06f8r9t2b4c6d8e0f2g4h6j8km",
"added": 1,
"replaced": 0,
"rejected": [
{
"reference": "client-0043",
"error": {
"code": "invalid_body",
"message": "company.postcode: company.postcode is not a Belgian postcode",
"details": {
"field": "company.postcode"
}
}
}
],
"matches": 7,
"meta": {
"request_id": "req_0192d3a4b5c67d8e9f0a1b2c3d4e5f63",
"warnings": []
}
}matches counts the accepted companies’ matches that are not not_eligible. The second company was rejected for a five-digit postcode; the first was added and matched.
Read the matches
curl "https://api.subsido.be/v1/watchlists/wl_06f8r9t2b4c6d8e0f2g4h6j8km/matches?company=client-0042" \ -H "Authorization: Bearer sb_live_..."| Parameter | Meaning |
|---|---|
| company | One company’s reference. Without it, every company’s matches. |
| include_not_eligible | Also the not_eligible ones, when the watchlist’s options keep them. Default false. |
| limit | Rows to return, 1 to 5,000 (default 500). This list does not page. |
The answer is { data, meta, disclaimer }. Each row is { company_reference, subsidy_id, match_status, score, result, subsidy_version, first_matched_at, updated_at }, where result is the match exactly as /v1/match computes it (status, confidence, relevance, reasons, unknowns, estimate), without the measure summary: read the measure with GET /v1/subsidies/{id}. subsidy_version is the version it was evaluated against.
Re-evaluation and events
The worker re-evaluates a watchlist whenever a measure it could match or one of its companies has changed since its last evaluation (last_evaluated_at). Background re-evaluation is included in the plan and never counts as match evaluations. Every difference becomes an event:
| Event | When |
|---|---|
| match.created | A measure starts to match a company (including at the first evaluation, when the companies are added). |
| match.status_changed | A match’s status changes, say from possibly_eligible to likely_eligible. previous_status says from what. |
| match.removed | A measure no longer matches: it closed, its rules changed, or the company’s facts did. |
Match events belong to the watchlist’s owner. They reach only that account’s webhooks (filter them with watchlists or event_types) and never appear in the public change feed.
{
"id": "chg_06f8s2m4d2a9b1c7e3g5h8j0kn",
"event": "match.created",
"created_at": "2026-09-27T07:00:03+02:00",
"data": {
"subject": "match",
"id": "wl_06f8r9t2b4c6d8e0f2g4h6j8km:client-0042:federal:investeringsaftrek",
"version": null,
"categories": [
"match.created"
],
"diff": {},
"summary": {
"watchlist_id": "wl_06f8r9t2b4c6d8e0f2g4h6j8km",
"company_reference": "client-0042",
"subsidy_id": "federal:investeringsaftrek",
"match_status": "likely_eligible",
"previous_status": null,
"subsidy": {
"title": {
"nl": "Investeringsaftrek",
"fr": "Déduction pour investissement",
"en": "Investment deduction",
"de": null
},
"status": "continuous",
"instrument_type": "tax_deduction",
"issuer": "FOD Financiën",
"closes_at": null,
"regions": [],
"topics": [
"investment",
"digitalisation"
],
"url": "https://financien.belgium.be/nl/ondernemingen/vennootschapsbelasting/belastingvoordelen/investeringsaftrek",
"source_id": "curated_federal"
}
}
}
}What we keep
Facts, not people
