Developers › Endpoints
Endpoints
Base URL https://syynilabs.fi/api/v1. All endpoints are GET, return JSON, and require the Authorization header.
| Endpoint | Cost | What it does |
|---|---|---|
/v1/companies/count | Free | How many companies match a filter. Returns both levels, because the same filter means a different number of companies and of decision-makers. |
/v1/companies | Billable | Company rows, cursor-paginated, with optional field groups. |
/v1/companies/{business_id} | Billable (one row) | A single company by business ID. Ceased companies are returned too — for an enrichment call, that is the most valuable single fact. |
/v1/companies/{business_id}/decision-makers | Billable per row | The decision-makers of one company. No pagination; capped at 200 rows, and the response says `truncated: true` if the cap cut the list. 404 if the business ID does not exist. |
/v1/decision-makers/count | Free | How many decision-maker rows match, and how many companies they come from. |
/v1/decision-makers | Billable | Decision-maker rows. One row is a person, not a company. |
/v1/filters | Free | Machine-readable list of every filter and field group. |
/v1/usage | Free | Your key's current-month spend, quotas and limits. |
Common parameters
| Parameter | Default | Notes |
|---|---|---|
fields | core only | Comma-separated field groups. core is always included. Unknown groups are rejected. |
page_size | 100 | 1–1000. Larger pages are cheaper in requests, not in rows. |
cursor | — | Opaque. Pass back verbatim from pagination.cursor. Tied to the filters and fields it was issued for. |
| filters | — | See the filter reference. Each parameter may be given once; repeats are an error. |
Field groups
Company rows:
| Group | Billable | Contents |
|---|---|---|
core | Yes | Identity, address, industry, register entries, and free availability flags telling you whether the premium groups would return anything for this row (has_decision_maker here means at least one named person, the same set the decision_makers group returns). |
web | No | Domain, detected technologies, site languages, online store. |
financials | No | Taxable income (NOT revenue), public-sector sales, funding. |
signals | No | Buying signals: tenders, hiring, certificates, patents, licences, register changes. |
phone | Yes | Phone numbers published on the company's own website, in confidence order, with the date last seen. |
email | Yes | The company's general email addresses (info@, sales@…). Named individuals' addresses belong to the decision-maker endpoints, not here. |
decision_makers | Yes | Named decision-makers with their role and title. |
Decision-maker rows:
| Group | Billable | Contents |
|---|---|---|
core | Yes | Role, title, employer and freshness — everything except the person's identity and contact details. |
name | Yes | The person's name. |
phone | Yes | The person's own direct number. Mobile is preferred when several are known — a switchboard does not reach a person. |
email | Yes | The person's work address: found directly, or derived from the organisation's address pattern. The response says which. |
Company rows
curl -H "Authorization: Bearer $SYYNI_API_KEY" \
"https://syynilabs.fi/api/v1/companies\
?municipality=091&industry_division=41&fields=web,phone&page_size=50"{
"data": [{
"business_id": "0100130-4",
"name": "Example Oy",
"company_form": { "code": "16", "description": "Osakeyhtiö" },
"industry": { "code": "41200", "description": "Construction of buildings",
"division": "41" },
"address": { "street": "Esimerkkitie 1", "postal_code": "00100",
"city": "Helsinki", "care_of": null,
"municipality_code": "091", "region_code": "01" },
"founded": "1998-03-12", "age_years": 28, "status": "active",
"registers": { "vat": true, "prepayment": true, "employer": true },
"availability": {
"has_phone": true, "phone_count": 3,
"has_email": true, "email_count": 1,
"has_decision_maker": true, "decision_maker_count": 4,
"has_domain": true
},
"web": { "website": "example.fi", "domain_count": 2,
"technologies": ["WordPress"], "site_languages": ["fi", "en"],
"is_ecommerce": false, "email_platform": "Microsoft 365",
"dmarc": "reject" },
"phone_numbers": ["+358401234567"], "phone_updated": "2026-08-16"
}],
"pagination": { "page_size": 50, "has_more": true, "cursor": "eyJrIjpb..." },
"billing": { "rows_returned": 50, "rows_billed": 50, "cost": "2.65",
"currency": "EUR", "vat": "excluded",
"field_groups": { "core": { "billed": 50, "empty": 0,
"free_repeat": 0 },
"phone": { "billed": 38, "empty": 12,
"free_repeat": 0 } } }
}status is active or ceased. List queries return only active companies unless you look one up by business ID.
taxable_income in the financials group is not revenue. It is confirmed taxable profit after deductions, and about two thirds of companies have zero. Use it for size banding, not for turnover thresholds.
Decision-maker rows
curl -H "Authorization: Bearer $SYYNI_API_KEY" \
"https://syynilabs.fi/api/v1/decision-makers\
?region=01&roles=toimitusjohtaja&fields=name,email&page_size=50"{
"data": [{
"business_id": "0100130-4",
"company_name": "Example Oy",
"role": "toimitusjohtaja",
"title": "Toimitusjohtaja, perustaja",
"occupation": null,
"last_seen": "2026-08-16",
"source": "https://example.fi/yhteystiedot",
"availability": { "has_phone": true, "has_direct_email": true,
"has_email_pattern": true },
"name": "Matti Meikäläinen",
"email": "matti.meikalainen@example.fi",
"email_source": "published"
}],
"pagination": { "page_size": 50, "has_more": false, "cursor": null },
"billing": { "rows_returned": 50, "rows_billed": 50, "cost": "5.30",
"currency": "EUR", "vat": "excluded",
"field_groups": {
"core": { "billed": 50, "empty": 0, "free_repeat": 0 },
"name": { "billed": 50, "empty": 0, "free_repeat": 0 },
"email": { "billed": 41, "empty": 9, "free_repeat": 0 } } }
}role is our classification; title is what the website actually said. An empty title means the page did not state a role — not that the person has none.
email_source is published when the address was read from the site and derived when it was constructed from the organisation's known address pattern (measured to be correct in about 96 cases out of 100). Both are billed the same, and you should treat a derived address with appropriate caution.
Pagination
Cursor-based, not offset. Offset pagination shifts under you when the data changes — and our crawler writes to these tables all day, so a row could appear twice or be skipped. With a metered API that is a billing dispute, not an inconvenience.
Results are ordered by business ID (and person ID at decision-maker level). Custom sorting is not available in v1, because keyset pagination requires a stable order.
Rate limits
Per-minute burst, daily requests, monthly rows and a monthly spend cap — all per key, all visible from /v1/usage. See Errors for how to handle them.