Two jobs: resolve vs search
Company is the customer-facing unit — any operator, supplier, studio, aggregator, platform, or PSP, licensed or grey. The Company API splits two different jobs:
- Resolve (
GET /companies/resolve) — "I know an identifier; give me the authoritative Company profile." Backed by our system of record. Returns the full nested profile: licenses, Domains, enumerated payment methods and game providers, and provenance. Addinclude[]=firmographicsonly when you need paid operating-organization data for one or more exact Domains. - Search (
GET /companies/search) — "I have criteria; give me ranked candidates." Returns thin discovery rows (categories + counts), not full profiles. Preview the size and cost first withGET /companies/search/preview.
$ help --topic=company-refEvery Company carries an opaquecompany_ref(e.g.igfc_3uSBTwEXnRo1rfvmRs6fgdMr). It is the only stable follow-up handle: store it and pass it back toresolve. Treat it as a black box — do not parse it, sort by it, or construct new refs from it. It is not an internal database id.
Resolve a Company
Resolve has two input modes:
company_refmode —company_refis authoritative and exclusive. Any natural identifiers sent alongside it are treated as assertions; a disagreement returns409 conflicting_lookup_input.- Natural identifier mode — use one or more natural identifiers. Resolve applies deterministic precedence
license_number→domain→legal_entity→name; lower-precedence inputs are echoed underignored_inputs.
Natural identifiers:
license_number(+ optionaljurisdiction) — a bare number matching multiple jurisdictions returns409 ambiguous_license_number(charge 0); resend withjurisdiction.domain— a casino URL or host. Canonicalized to its registrable domain (scheme / subdomain / path / IDN stripped), then resolved to every Company behind it: licensee companies plus the brand owner, each tagged inmatched_as(licensee,brand_owner, or both). An un-normalizable input (IP or junk) returns400 invalid_domain; a normalizable domain absent from our data returns404 not_found.legal_entity— exact legal company name match.name— exact company/brand name; collisions returnmatches[]candidates (charge 0).
Resolve does not fall through to a lower-precedence natural identifier when the highest-precedence input is ambiguous.
GET /companies/resolve
COST 3 credits / profile returned
Resolve a natural identifier or an opaque company_ref to the authoritative Company profile(s). Charged per profile successfully returned.
/v1/companies/resolve
Authorization
Query
Opaque public handle (igfc_…). Authoritative and exclusive.
License number; pair with jurisdiction when a bare number is ambiguous.
mga, ukgc, curacao, anjouan
Casino URL or host. Canonicalized to its registrable domain, then resolved to licensee + brand-owner Companies. IP/junk → 400 invalid_domain.
Exact legal company name
Exact company or brand name
Closed include catalog. Pass firmographics explicitly for the paid Domain-scoped composition.
Exact eligible Domain selector (igfd_…). With firmographics requested, omission intentionally fans out across every eligible Company Domain.
Refresh Domain firmographics older than N days; 0 forces a refresh.
When true (the server default), a transient refresh failure may return the latest successful result as stale.
Hard cost ceiling. Rejected (402) before any payload if exceeded.
Example response200
{
"success": true,
"data": {
"resolved_by": "company_ref",
"ignored_inputs": {},
"input_company_ref": "igfc_3uSBTwEXnRo1rfvmRs6fgdMr",
"resolved_company_ref": "igfc_3uSBTwEXnRo1rfvmRs6fgdMr",
"ref_status": "active",
"companies": [
{
"company_ref": "igfc_3uSBTwEXnRo1rfvmRs6fgdMr",
"company_name": "Medium Rare N.V.",
"legal_entity": "Medium Rare N.V.",
"role": "operator",
"matched_as": [],
"domains": [
{ "domain_ref": "igfd_9mT7…", "domain": "stake.com", "inferred_geo": null }
],
"licenses": [
{ "jurisdiction": "curacao", "license_number": "…", "status": "active",
"license_type": "…", "authorized_domains": [
{ "domain_ref": "igfd_9mT7…", "domain": "stake.com", "inferred_geo": null }
] }
],
"payment_methods": ["Bitcoin", "Visa"],
"payment_categories": ["crypto", "card"],
"game_providers": ["Evolution"],
"affiliate_program": true,
"geo_hints": ["EN"],
"data_completeness": 0.82
}
],
"billing": {
"returned_count": 1,
"credits_per_profile": 3,
"credits_charged": 3,
"billing_reason": "company_profile_delivered"
}
}
}
company_ref lifecycle
An active company_ref resolves to exactly one Company. Stale refs are managed-stable: every company_ref-mode response echoes ref_status.
ref_status |
Meaning | Charge |
|---|---|---|
active |
Resolves to one Company | per profile |
redirected |
Merged — resolved_company_ref is the survivor |
per profile |
ambiguous |
Split with no single owner — matches[] carries the new refs (409) |
0 |
retired |
Withdrawn — no profile | 0 |
Every materialized Domain carries an opaque domain_ref (for example, igfd_9mT7…). Store it as the managed-stable selector for Domain-scoped follow-up requests; do not derive or construct it.
Paid Domain-scoped firmographics
firmographics is an explicit paid composition on Company resolve. It is never included in the base profile. The operating organization is matched from an exact eligible Domain; the resolver never guesses from the Company's legal name.
curl -G -H "X-API-Key: igf_demo_9457cf242d0c43404fb69b8273d7f4371716682a12c74e3c3274fd8957ebeae7" \
-H "Idempotency-Key: $(uuidgen)" \
--data-urlencode "company_ref=igfc_3uSBTwEXnRo1rfvmRs6fgdMr" \
--data-urlencode "include[]=firmographics" \
--data-urlencode "domain_ref=igfd_9mT7…" \
--data-urlencode "max_age_days=30" \
--data-urlencode "allow_stale_on_error=true" \
"https://api.igamingfinder.com/v1/companies/resolve"
- With
domain_ref, exactly that related Domain is selected. - Without
domain_ref, every deduplicated eligible Domain is selected in deterministic order. This is intentional fan-out, not "pick the first Domain." max_creditsis checked against the profile plus all candidate Domains before any refresh starts.- Each available fresh, cached, or stale Domain result uses the configured per-result rate below. Unavailable results remain in the array and cost zero optional credits.
allow_stale_on_errordefaults totrue. Set it tofalsewhen a failed refresh must produce an unavailable result instead of the latest successful value.
Cost: 12 credits / delivered Domain result
The billing block reconciles the composite delivery explicitly: returned_count × credits_per_profile plus firmographics_returned_count × credits_per_firmographics_result equals credits_charged for a paid response.
When requested, firmographics is always an array, including [] when there are no eligible Domains:
{
"firmographics": [
{
"domain": { "domain_ref": "igfd_9mT7…", "domain": "stake.com", "inferred_geo": null },
"available": true,
"cached": true,
"stale": false,
"reason": null,
"fetched_at": "2026-07-15T12:00:00Z",
"refresh": {
"attempted": false,
"status": "not_attempted",
"reason": null,
"attempted_at": null
},
"data": {
"name": "Stake",
"description": null,
"website": "https://stake.com",
"linkedin_url": "https://www.linkedin.com/company/stake-com",
"industry": "Gambling Facilities and Casinos",
"employee_count": 500,
"company_size": [201, 500],
"founded_year": 2017,
"headquarters": { "city": "Limassol", "region": null, "country": "Cyprus", "postal_code": null }
}
}
]
}
The payload is closed and brand-neutral: only documented fields are returned. Raw source responses, source-specific IDs, internal cost events, and error text are never exposed.
Search Companies
Preview first to see the result size and cost, then pull paid rows. Search rows are thin discovery candidates — they carry payment/provider categories and counts, never the enumerated value lists, nested licenses, or full domain mappings (those are resolve-only). Their index-derived Domain samples can have domain_ref: null; pivot through the row's company_ref to resolve for materialized Domain selectors.
GET /companies/search/preview
COST 0 credits / request
Free anti-surprise preview — total match count, allowlisted facet counts, per-page_size cost estimates, and a tiny redacted sample. No paid payload.
/v1/companies/search/preview
Authorization
Query
Free-text query
operator, aggregator, platform_provider, payment_provider, game_studio, affiliate_software, affiliate_media, other_supplier
mga, ukgc, curacao, anjouan
Registrable domain; applied as an exact filter (canonicalized). IP/junk → 400 invalid_domain.
GET /companies/search
COST 1 credit / result returned
Paid ranked discovery rows. Charged per row successfully returned (page_size × credits_per_result is the maximum), guarded by max_credits.
/v1/companies/search
Authorization
Query
Registrable domain; applied as an exact filter (canonicalized). IP/junk → 400 invalid_domain.
Rows per page (max 100). You are charged per row returned.
Hard cost ceiling for this pull.
Example response200
{
"success": true,
"data": {
"query": { "payment_category": "crypto", "jurisdiction": "anjouan" },
"total": 137,
"page": 1,
"page_size": 20,
"hits": [
{
"company_ref": "igfc_7Qz…",
"company_name": "Medium Rare N.V.",
"role": "operator",
"primary_domain": { "domain_ref": null, "domain": "stake.com", "inferred_geo": null },
"domains_sample": [
{ "domain_ref": null, "domain": "stake.com", "inferred_geo": null }
],
"domain_count": 1,
"jurisdictions": ["anjouan"],
"license_statuses": ["active"],
"license_count": 1,
"payment_categories": ["crypto", "card"],
"payment_method_count": 2,
"game_provider_count": 1,
"affiliate_program_present": true,
"rank": 1
}
],
"billing": {
"returned_count": 20,
"credits_per_result": 1,
"credits_charged": 20,
"page_size": 20,
"billing_reason": "search_rows_delivered"
}
}
}
People contacts for a Company
GET /companies/:company_ref/people returns decision-maker contacts for a resolved Company. It is separate from GET /companies/resolve because people are not part of the base Company profile and the cost scales with contacts returned.
GET /companies/:company_ref/people
COST 9 credits / contact returned
Return decision-maker contacts for a resolved Company. Charged per contact returned.
/v1/companies/:company_ref/people
Authorization
Query
Company ref. The public demo key only accepts this stable demo ref.
Optional role search, e.g. payments, compliance, affiliate, marketing.
Contacts requested. Billing is per contact returned.
Freshness knob (ADR-0050). Serve owned-store cache if younger than N days; 0 forces a fresh pull from the source.
Billing
Charge-on-success delivery billing: you pay only for paid payload actually returned.
| Operation | Cost |
|---|---|
| Enrich domain | 10 credits (0 if cached) |
| Cached enrichment result | 0 credits / request |
Create export (POST /exports) |
Variable (based on result count) |
| All status/poll endpoints | 0 credits / request |
Get account info (GET /account) |
0 credits / request |
| Sales Intelligence Brief workspace | Included with Sales Intelligence access |
| Lobby monitor (on-demand run) | 10 credits / run |
Company search preview (count/facets/cost) (GET /companies/search/preview) |
0 credits / request |
Company search result row (GET /companies/search) |
1 credit / result returned |
Company resolve profile (GET /companies/resolve) |
3 credits / profile returned |
Domain verdict resolve (GET /domains/resolve) |
1 credit / verdict returned |
Domain search result row (GET /domains/search) |
1 credit / result returned |
Domain resolve — Operator Launch Profile (GET /domains/resolve?include[]=operator_launch_profile) |
5 credits / delivered profile |
Company resolve — firmographics result (GET /companies/resolve?include[]=firmographics) |
12 credits / delivered Domain result |
Company people — contact (GET /companies/:company_ref/people) |
9 credits / contact returned |
Licensed market entry Signal (GET /signals/market-entries) |
1 credit / Signal returned |
License search preview (count/facets/cost) (GET /licenses/search/preview) |
0 credits / request |
License search result row (GET /licenses/search) |
1 credit / result returned |
License resolve profile (GET /licenses/resolve) |
3 credits / profile returned |
- No charge for: empty results,
not_found, validation/conflict errors, ambiguous disambiguationmatches[], retired refs with no profile, or amax_creditsrejection before delivery. - Paid
GETs are non-cacheable (Cache-Control: no-store). To make a retry safe, send anIdempotency-Keyheader — a retry with the same key and request replays the original charge instead of charging again. companies/resolvehas no free preview; usemax_creditsas its cost control. For Domain firmographics, the preflight ceiling includes the base profile and every candidate Domain. A rejected request returnsrequired_creditsso you can narrow withdomain_refor raise the ceiling.
$ help --topic=domain-inputsdomaininputs toresolve,search, andsearch/preview(anddomainassertions alongside acompany_ref) are canonicalized through the shared domain normalizer — URL / subdomain / path / IDN / punycode reduce to the stored registrable domain — before matching. An un-normalizable input (IP or junk) returns400 invalid_domainrather than an empty result.