Company API

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 Company profile." Backed by our system of record. Returns the supported customer profile: licenses, Domains, enumerated payment methods, and content suppliers. Add include[]=firmographics only 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 with GET /companies/search/preview.
$ help --topic=company-ref
Every Company carries an opaque company_ref (e.g. igfc_3uSBTwEXnRo1rfvmRs6fgdMr). It is the only stable follow-up handle: store it and pass it back to resolve. Treat it as a black box — do not parse it, sort by it, or construct new refs from it. It is not a database ID.

See Data Availability for current payment, provider, affiliate, export, and demo coverage, and what a missing value means.

Returned Company fields

Resolve profile

GET /companies/resolve supports these customer fields for each Company:

Group Fields
Identity company_ref, company_name, subject_kind, legal_entity, role, country, matched_as, brands
Catalog domains, licenses, apps
Observed data payment_methods, payment_categories, supplier_brands, platform_brands, affiliate_program, geo_hints
Completeness and time data_completeness, last_observed_at, last_updated_at
Optional firmographics only when requested with include[]=firmographics

Each licenses[] item has license_ref, jurisdiction, license_number, status, license_type, and authorized_domains. Each apps[] item has store, app_id, and url.

Search row

GET /companies/search supports these customer fields for each ranked hit:

Group Fields
Identity company_ref, company_name, subject_kind, legal_entity, role
Domain and license summary primary_domain, domains_sample, domain_count, jurisdictions, license_statuses, license_count
Observed summaries payment_categories, payment_method_count, supplier_brand_count, conference_count, platform_present, affiliate_program_present, geo_hints

conference_count counts the conferences the company was seen exhibiting at, one per dated event: a firm standing at SiGMA Malta 2026 and SiGMA Rome 2026 counts two, and two stands at one show count one. It is 0, never absent, for a company we have seen at none. | Completeness and time | data_completeness, last_observed_at, last_updated_at | | Ranking | rank, score, matched_fields, highlight | | Availability hints | firmographics_available, contacts_available |

Resolve a Company

Resolve has two input modes:

  • company_ref mode — company_ref is authoritative and exclusive. Any natural identifiers sent alongside it are treated as assertions; a disagreement returns 409 conflicting_lookup_input.
  • Natural identifier mode — use one or more natural identifiers. Resolve applies deterministic precedence license_numberdomainlegal_entityname; lower-precedence inputs are echoed under ignored_inputs.

Natural identifiers:

  • license_number (+ optional jurisdiction) — a bare number matching multiple jurisdictions returns 409 ambiguous_license_number (charge 0); resend with jurisdiction.
  • 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 in matched_as (licensee, brand_owner, or both). An un-normalizable input (IP or junk) returns 400 invalid_domain; a normalizable domain absent from our data returns 404 not_found.
  • legal_entity — exact legal company name match.
  • name — exact company/brand name; collisions return matches[] 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 Company profile(s). Charged per profile successfully returned.

GET /v1/companies/resolve
Authorization
string
Query
string

Opaque public handle (igfc_…). Authoritative and exclusive.

string

License number; pair with jurisdiction when a bare number is ambiguous.

string

mga, ukgc, curacao, anjouan

string

Casino URL or host. Canonicalized to its registrable domain, then resolved to licensee + brand-owner Companies. IP/junk → 400 invalid_domain.

string

Exact legal company name

string

Exact company or brand name

string

Sections to add. Pass firmographics explicitly for the paid firmographics section, billed per Domain.

string

Exact eligible Domain selector (igfd_…). With firmographics requested, leave it out to get every eligible Company Domain.

integer

Refresh Domain firmographics older than N days; 0 forces a refresh.

boolean

When true (the server default), a transient refresh failure may return the latest successful result as stale.

integer

Hard cost ceiling. Rejected (402) before any data is returned 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"],
        "supplier_brands": ["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 Domain in a profile carries an opaque domain_ref (for example, igfd_9mT7…). Store it as the stable selector for follow-up requests about that Domain; do not derive or construct it.

firmographics is a paid section that you request explicitly 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.

bash
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. All of them are returned, not only the first Domain.
  • max_credits is 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_error defaults to true. Set it to false when 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:

json
{
  "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 response contains only the documented fields and never names a data supplier. Raw source responses, source IDs, our cost records, and source error text are never included.

Search Companies

Preview first to see the result size and cost, then pull paid rows. Search rows are short discovery results — they carry payment/provider categories and counts, never the enumerated value lists, nested licenses, or full domain mappings (those are resolve-only). Their Domain samples can have domain_ref: null; call resolve with the row's company_ref to get a domain_ref for each Domain.

GET /companies/search/preview

COST 0 credits / request

Free anti-surprise preview — total match count, counts per filter value, per-page_size cost estimates, and a tiny redacted sample. No paid data.

GET /v1/companies/search/preview
Authorization
string
Query
string

Free-text query

string

operator, aggregator, platform_provider, payment_provider, game_studio, affiliate_software, affiliate_media, other_supplier, unknown

string

mga, ukgc, curacao, anjouan

string
string
string
boolean
string

Registrable domain; applied as an exact filter (canonicalized). IP/junk → 400 invalid_domain.

A successful preview with matches includes next_action.href: a ready paid-search URL with the same public filters, at most 10 rows, and max_credits set to the quoted cost of that call. It is null when nothing matches.

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.

GET /v1/companies/search
Authorization
string
Query
string
string
string
string
string
string
string
boolean

False means no reviewed platform is published, not that the Company has no platform.

string

Registrable domain; applied as an exact filter (canonicalized). IP/junk → 400 invalid_domain.

integer
integer

Rows per page (max 100). You are charged per row returned.

integer

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,
        "supplier_brand_count": 1,
        "conference_count": 2,
        "platform_present": true,
        "affiliate_program_present": true,
        "geo_hints": ["en"],
        "data_completeness": 0.82,
        "last_observed_at": "2026-08-24T10:30:00Z",
        "last_updated_at": "2026-08-24T10:35:00Z",
        "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.

role narrows the page. A glossary key is a named, measured filter — ceo, cto, marketing_leads, affiliates, compliance, payments, product_leads, decision_makers — published with its meaning, coverage and matched spellings by the free GET /people/roles. Any other term is free text and matches as a substring. Terms combine with OR or commas, and the result is their union.

The job title decides the match, so a person's headline is only read when they carry no title at all, and a headline role is dropped when every company written after a role in that headline belongs to somebody else: "Founder, APEX CREATOR LABS" under an employer of Acme Bet is not an Acme Bet CEO. A headline that names no company still counts. Exclusions are applied to whichever of the two matched. That is why role=ceo does not hand you a "Vice President Human Resources".

GET /companies/:company_ref/people

COST 9 credits / contact returned

Return decision-maker contacts for a resolved Company. Charged per contact returned.

GET /v1/companies/:company_ref/people
Authorization
string
Query
string

Company ref. The public demo key only accepts this stable demo ref.

string

Optional role filter: a glossary key from GET /people/roles, or free text. Combine terms with OR.

boolean

Free. How many people on file each glossary role would return, as `role_counts`; no source is called and nothing is charged. A company with nobody on file answers `available: false, reason: not_cached`. Each delivered contact carries the `role_key` it answers to.

integer

Contacts requested. Billing is per contact returned.

integer

Serve stored data if it is younger than N days; 0 always fetches fresh data from the source.

Billing

Charge-on-success delivery billing: you pay only for paid data actually returned.

OperationCost
Enrich domain 10 credits (0 if cached)
Cached enrichment result 0 credits / request
Create export (POST /exports) Variable (number of results × the matching resolve price)
All status/poll endpoints 0 credits / request
Get account info (GET /account) 0 credits / request
Prospect lists (list, show, download) Included with your prospect lists
Lobby monitor (on-demand run) 10 credits / run
Company search preview (count and 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
Logo catalogue search (GET /logos/search) Free
People role glossary (GET /people/roles) Free
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
Platform new-site Signal (GET /signals/platform-sites) 1 credit / Signal returned
Official register change Signal (GET /signals/register-changes) 1 credit / Signal returned
License search preview (count and 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 disambiguation matches[], withdrawn refs with no profile, or a max_credits rejection before delivery.
  • Paid GETs are non-cacheable (Cache-Control: no-store). To make a retry safe, send an Idempotency-Key header — a retry with the same key and request replays the original charge instead of charging again.
  • companies/resolve has no free preview; use max_credits as its cost control. For Domain firmographics, the preflight ceiling includes the base profile and every candidate Domain. A rejected request returns required_credits so you can narrow with domain_ref or raise the ceiling.
$ help --topic=domain-inputs
domain inputs to resolve, search, and search/preview (and domain assertions alongside a company_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) returns 400 invalid_domain rather than an empty result.