Company Identity Resolver avatar

Company Identity Resolver

Pricing

from $5.95 / 1,000 results

Go to Apify Store
Company Identity Resolver

Company Identity Resolver

Resolves a company name to its primary domain and LinkedIn URL, one company or a batch of names and domains with one row per entry. Any mix of name, domain, or LinkedIn URL in; one canonical identity out with 0-100 confidence scores, conflict detection, and a match method. Flat, Clay-ready.

Pricing

from $5.95 / 1,000 results

Rating

0.0

(0)

Developer

Mamba Labs

Mamba Labs

Maintained by Community

Actor stats

0

Bookmarked

21

Total users

10

Monthly active users

3 hours ago

Last modified

Share

๐Ÿชช What can Company Identity Resolver do?

Give it a company name, and it returns the company's primary domain and LinkedIn company URL. Give it any combination of name, domain or LinkedIn URL, one company or a batch list, and it returns one canonical company identity per row: name, primary domain and LinkedIn company URL, each with a 0 to 100 confidence score.

Give it whatever you have. It resolves the missing fields, cross-checks the ones you supplied, and flags disagreements rather than silently merging them.

๐Ÿ“ฆ What you getโš™๏ธ Features and integrations
๐Ÿชช A canonical name, domain and LinkedIn URL
๐Ÿ’ฏ Per-field and overall confidence, 0 to 100
โš”๏ธ Conflict detection, never a silent merge
๐Ÿงพ 19 flat fields, snake_case, one row per entity
๐Ÿ“š Batch mode, lists of names and domains in one run
๐Ÿ”„ Any input, any direction, name, domain or slug
๐Ÿงฌ Canonical name from the company's own JSON-LD
๐ŸงŠ 7 day cache, repeat lookups skip the network, not the per-row charge
โฌ‡๏ธ Export to JSON, CSV, Excel, HTML or XML

Bought by Clay users, RevOps teams, outbound agencies and agent builders who need a reliable dedupe and join key for company records. It is the join primitive the rest of a GTM stack hangs off.

๐Ÿšซ This resolves identity, it does not enrich. It will not tell you headcount, industry or revenue. For that, join on the domain it returns and use Company Firmographic Enricher.

๐Ÿ’ก Why use Company Identity Resolver?

If you wantRead these fields
A stable join key across systemsdomain
The company's real namename, name_confidence
Their LinkedIn pagelinkedin_url, linkedin_confidence
To know whether to trust the matchconfidence_score, match_method
To catch bad merges before they happenmatch_method = "conflict"
What you originally suppliedinput_company_name, input_domain, input_linkedin

โš”๏ธ Conflicts are surfaced, never merged

When your inputs disagree, a domain that says one company and a LinkedIn slug that says another, the row comes back with match_method: "conflict" and a capped score.

That is the single most valuable thing this actor does. A resolver that quietly picks one side writes a bad join key into your CRM and you find out months later. This one hands the disagreement back to you.

๐Ÿงญ How resolution works

  1. Anchor the domain, which is the canonical key. A provided domain is validated by DNS. With no domain, a search bridges the name or LinkedIn slug to the company's own domain, ranking candidates by result position and stem similarity and excluding aggregator hosts.
  2. Confirm identity on the homepage. The resolved homepage is fetched and its schema.org/Organization JSON-LD is read for the self-declared canonical name and the sameAs LinkedIn URL.
  3. Anchor the LinkedIn URL, and verify it. The one you provided is returned as given (counted as validated when the homepage sameAs names the same page). Otherwise the homepage's own link wins: its sameAs, or a plain link to a LinkedIn company page. Otherwise the actor collects LinkedIn pages from a Brave search restricted to linkedin.com/company (Bing as the fallback engine), then DuckDuckGo, then an optional Serper (Google results API) backup, stopping as soon as one page verifies. A search result page verifies when its name is identical to the name the company site declares (linkedin_confidence 85) or to the name you provided (80), or when its slug is one the domain implies and its name is identical to the domain name, and the domain exists (75). "Identical" means equal after lowercasing and removing punctuation and legal words such as Inc, Ltd, and Group. A page under minLinkedinConfidence (default 70) is not returned: linkedin_url is null and linkedin_verification names what was seen and why it was held back. A row with no LinkedIn page is marked degraded: true and degradation_reason names the steps it tried.

No request is sent to LinkedIn at any step. The LinkedIn URL is read from the company's own homepage or from a search result link. Every request is capped by the time left in the run, so a slow search engine cannot run the clock out.

Aggregator domains (LinkedIn, Crunchbase, Bloomberg, Wikipedia and the like) are excluded as candidate domains. Common names, holding companies and recent rebrands are scored down rather than guessed at.

โ–ถ๏ธ Ready-to-run examples

ExampleWhat it does
Company Name to Domain FinderResolve a company name to its primary domain
Same Company Conflict CheckerCheck whether two records refer to the same company
Domain to LinkedIn Company URL LookupResolve a domain to its LinkedIn company page
CRM Dedup Key BuilderGenerate a dedupe key for CRM company matching
LinkedIn Slug to Company DomainReverse-resolve a LinkedIn slug back to the domain
Batch Company Names to DomainsA list of names, one run, one row each

๐Ÿ“‹ What data can Company Identity Resolver extract?

19 fields per entity, flat and snake_case, no nested objects.

FieldWhat it holds
nameThe canonical company name, preferring the company's own declaration
domainThe primary domain, the canonical key
linkedin_urlThe LinkedIn company URL
confidence_scoreOverall 0 to 100 blend
domain_confidence, linkedin_confidence, name_confidencePer-field scores
linkedin_verificationThe evidence behind a returned LinkedIn URL, or why none was returned
match_methodHow the identity was resolved, including conflict
resolvedWhether a usable identity came back
input_company_name, input_domain, input_linkedinEchoed back, so the row is self-describing
run_dateWhen the run happened
degraded, degradation_reasonWhether a step could not run, and why
row_statusok, degraded, or notice (a run level message such as the free plan cap)
error_reasonWhy the row is degraded or a notice; null on an ok row
billable_events_jsonThis row's billing receipt, for example [{"event":"apify-default-dataset-item","count":1}]

Every row carries every key. A value that is unknown is null, never a missing key.

โš ๏ธ Threshold on confidence_score rather than on resolved. Name-to-domain resolution is inherently ambiguous for very common names, holding companies and recent rebrands. The actor puts that ambiguity in the score instead of hiding it, which only helps if you read it. For a high-trust pipeline, gate on the score and route the rest to manual review.

โš ๏ธ false and null mean different things on every row. false is a measurement: the actor looked and the answer was no. null is the absence of one: the actor could not look. When something it needed fails, the row comes back with degraded: true, a plain-language degradation_reason, and every field it could not measure set to null rather than to a confident false or 0. Filter on degraded before you trust a negative.

๐Ÿ› ๏ธ How to resolve a company to a canonical identity

  1. Open the Input tab and supply whatever you have: company_name, domain, linkedin_url, or any mix.
  2. Click Start.
  3. Read domain as your join key and confidence_score as your gate.
  4. Route any row with match_method: "conflict" to review rather than into your CRM.

The Input tab opens with Stripe and stripe.com filled in. That run returns one row: stripe.com, https://www.linkedin.com/company/stripe from the homepage sameAs, match_method: "exact_domain", confidence_score 100 (measured 2026-10-12).

๐Ÿ“š Batch mode: a list of names or domains in one run

Put company names in company_names, domains in domains, or both, one per line, and click Start. Every entry runs the same resolution path as a single lookup and writes its own row, in input order, with its own confidence_score and match_method. A row that fails returns a degraded row with degradation_reason set and the rest of the batch continues.

{
"company_names": ["Stripe", "Notion", "Figma", "Linear", "Vercel"],
"batchSize": 2
}

Returns five rows, one per name:

input_company_namenamedomainlinkedin_urlmatch_methodconfidence_score
StripeStripestripe.comhttps://www.linkedin.com/company/stripesearch_resolved90
NotionNotionnotion.comhttps://www.linkedin.com/company/notionsearch_resolved79
FigmaFigmafigma.comhttps://www.linkedin.com/company/figmasearch_resolved90
LinearLinearlinear.apphttps://www.linkedin.com/company/linearsearch_resolved79
VercelVercel Inc.vercel.comhttps://www.linkedin.com/company/vercelsearch_resolved90

(Measured on a live run of build 0.0.27, 2026-09-19, batchSize 5, 19 seconds for the five rows.)

When company_names and domains have the same number of entries, name 1 is resolved with domain 1, name 2 with domain 2, and so on, which is the shape of a spreadsheet with both columns. When the lengths differ, each list contributes its own rows, names first. batchSize is how many companies resolve at the same time (default 2, maximum 10; more concurrency meets search refusals sooner, so raise it for speed only if you accept more unresolved rows). When either list has at least one entry, batch mode takes precedence over the single fields. The price per row is the same as a single lookup; a batch pays the Actor start event once per run instead of once per company. From the API, the same input works with POST /v2/acts/mambalabs~company-identity-resolver/runs.

๐Ÿงช Using it in Clay

Add an Apify enrichment column and map whichever columns you have. Every input is accepted as a string, which is what Clay sends.

Supplying more than one identifier is better, not worse: extra inputs are cross-checked rather than overridden, and a conflict between them is exactly the signal you want before a merge.

๐Ÿ”‘ Using it as a dedupe key

Run it across two systems and join on domain. Because the domain is DNS-validated and aggregator hosts are excluded, it is stable in a way a name never is. Gate on domain_confidence when the domain came from a search rather than from your own input.

๐Ÿ’ต How much does it cost to resolve a company identity?

You are charged once per entity resolved (the apify-default-dataset-item event).

PlanPer entityPer 1,000 entities
Free$0.007$7.00
Bronze$0.00665$6.65
Silver$0.0063$6.30
Gold$0.00595$5.95

There is also a start event, apify-actor-start, at $0.00005, charged once per run per GB of memory. A batch run pays it once for the whole list.

Free plan monthly cap

Free Apify plan users get 400 fresh resolutions per calendar month, reset each month. A run that reaches the cap stops and returns a notice row. Paid Apify plans are not capped.

Maximum charge

The actor honors the maximum cost per run you set in Apify: when the platform reports that limit reached, the run stops cleanly and keeps every row already charged. You can also set max_charge_usd on the Input tab as a second ceiling; the run stops before any charge that would cross it.

The optional Serper backup search bills on your own Serper account, not through Apify: at most 2 queries per company, and only when the free steps found no LinkedIn page. Serper's published pricing (serper.dev, read 2026-09-17) is 2,500 queries free on signup, then $50 for 50,000 credits ($0.001 per query), with lower unit prices on larger packs. One credit per successful response.

๐Ÿ’ณ A low-confidence or conflicted result is still billed. The actor did the resolution work and a flagged conflict is a real, useful answer, often the most useful one it produces.

๐Ÿ“… Scheduled pricing change, 2026-10-26 12:00 UTC. Results move from Apify's default per-row event to a named result event at the same price on every plan, so each result row costs exactly what it costs today. A run summary row and a blocked lookup row stop being charged. Until then every row is billed as described above.

โš ๏ธ A cached repeat lookup is served instantly but is still billed. This actor prices per result row, and Apify charges that event for every row written to the dataset, whether the answer came from the network or from the 7 day cache. Corrected 2026-08-12: an earlier version of this section said repeat lookups inside the cache window were not charged. They are, and they always were. Measured on 2026-08-12, an identical lookup 16 minutes after the first was charged one result event. The cache saves you the wait and the platform usage, not the per-row price.

โŒจ๏ธ Input

Everything is on the Input tab. Supply at least one of the first three.

FieldTypeDefaultWhat it does
company_namestringnoneThe company name, however you have it written.
domainstringnoneBare domain. Validated by DNS when supplied.
linkedin_urlstringnoneA LinkedIn company URL or slug.
skipCachestring"false""true" forces a fresh resolution.
company_namesarray of stringsnoneBatch mode. One row per name. Paired with domains by position when both lists have the same length.
domainsarray of stringsnoneBatch mode. One row per domain, or paired with company_names.
batchSizeinteger2Companies resolved concurrently per wave in batch mode, 1 to 10.
minLinkedinConfidencestring"70"The floor, 0 to 100. A LinkedIn page the actor finds is returned only when its linkedin_confidence is at least this. A URL you provide is always returned.
max_charge_usdnumbernoneOptional ceiling in USD for this run's charges. The run stops before crossing it.
serperApiKeystring (secret)noneYour Serper API key. Enables the backup Google search for the LinkedIn page, at most 2 queries per company, only when the free steps found nothing. Also read from the SERPER_API_KEY environment variable.

๐Ÿ“ค Output

One flat row per entity, exportable as JSON, CSV, Excel, HTML or XML.

{
"input_company_name": "Stripe",
"input_domain": null,
"input_linkedin": null,
"name": "Stripe",
"domain": "stripe.com",
"linkedin_url": "https://www.linkedin.com/company/stripe",
"confidence_score": 96,
"match_method": "search_then_jsonld",
"domain_confidence": 95,
"linkedin_confidence": 95,
"linkedin_verification": "verified: the company homepage declares this page in its structured data (sameAs) (score 95)",
"name_confidence": 96,
"resolved": true,
"degraded": false,
"degradation_reason": null,
"run_date": "2026-06-21T09:36:04Z",
"row_status": "ok",
"error_reason": null,
"billable_events_json": "[{\"event\":\"apify-default-dataset-item\",\"count\":1}]"
}

degraded is true when no LinkedIn company page was found, and degradation_reason lists the steps tried in order, for example

no LinkedIn company page found; steps tried: slug_pattern, search_results, duckduckgo_search, serper_search (skipped: no Serper key); last step: serper_search (skipped: no Serper key)
.

๐Ÿงฏ What a blocked row and a summary row mean

A degraded row whose degradation_reason starts with no LinkedIn company page found is an answer: the search engines replied and none of them carried the company's page.

A degraded row whose degradation_reason starts with blocked: or timed_out: is not an answer. Every LinkedIn search engine refused the request, or the run ran out of time before one replied, and the reason says "this is not a confirmed absence". Rerun those rows.

A run that writes no company row at all, for example because the run budget ran out before the first row, writes one summary row instead and still finishes successfully. It has match_method: "unresolved", degraded: true, and a degradation_reason that starts with run_outcome= (no_results, blocked, or timed_out), then names the search engines reached and blocked, the run ID, and the build. It is never a company.

When the run's time is nearly spent, the actor stops starting new rows, keeps every row it already wrote, and says how many rows it did not start in the run's status message.

๐Ÿ’ก Tips

  • Supply every identifier you have. Cross-checking is free and a surfaced conflict is worth more than a confident wrong answer.
  • Join on domain, not on name. Names change; domains rarely do.
  • Route match_method: "conflict" rows to a human. That is what the flag is for.
  • Repeat lookups inside 7 days come from the cache, so re-running a list is fast; every row is still billed, cached or not (see the cost section).
  • Have a list already? Put it in company_names or domains and run once. One row per entry, same price per row, one Actor start event instead of one per company.

โš ๏ธ Known limits

Name-to-domain resolution is inherently ambiguous for very common names, holding companies and recent rebrands. The actor surfaces this in the confidence score rather than hiding it. Threshold on confidence_score for high-trust pipelines.

LinkedIn is a corroborating anchor, not a content source. No request is sent to LinkedIn. The URL comes from the company's homepage, or from a search result whose name verifies against the company. No personal profiles are read and no page content is extracted.

Verification trades fill for accuracy. On a 111 company test set, the share of rows with a LinkedIn URL fell from 98 percent to 79 percent when verification shipped on 2026-10-12, and the share of rows with a wrong URL fell from 28 percent to 13 percent. A company whose site blocks automated visits, whose site declares a different name from its LinkedIn page, and who links no LinkedIn page, comes back with no LinkedIn URL rather than a guess.

A provided LinkedIn URL is checked against the homepage, not against LinkedIn. When the homepage sameAs names the same page, linkedin_confidence is 95; otherwise it is 80.

Public data only. No Crunchbase, no LinkedIn login, no paid third-party API.

Resolution quality depends on the search stage when you supply no domain. If you already have a domain, supply it: it is the canonical key and providing it skips the least certain step entirely.

Results are cached for 7 days. Set skipCache to "true" to force a fresh resolution.

โ“ FAQ

What does match_method: "conflict" mean?

Your inputs disagreed. A domain pointed at one company and a LinkedIn slug at another. The score is capped and the row is handed back to you rather than merged.

Which field should I use as a join key?

domain. It is DNS-validated and aggregator hosts are excluded, so it is stable across systems in a way a company name is not.

Does it read LinkedIn profiles?

No. The actor sends no request to LinkedIn and never reads a personal profile. A LinkedIn URL comes from the company's own homepage or from a search result link.

Why is confidence low on a company I recognize?

Usually a common name, a holding company or a recent rebrand. Supplying the domain removes the ambiguity entirely.

Can I resolve many companies in one run?

Yes. Put names in company_names or domains in domains (one per line in the Console, a JSON array from the API) and every entry gets its own row. A failed row is marked degraded and does not stop the batch.

Can I give it just a LinkedIn slug?

Yes. It reverse-resolves the slug back to the company's own domain.

๐Ÿงฉ Want other GTM data?

Mamba Labs builds custom actors for B2B go-to-market teams. The public versions of that work live here on the Store, so our users get the same tooling we build under contract.

๐Ÿ•ต๏ธ Agent Accessibility Auditor๐Ÿค– AI Tooling Detector
๐Ÿ“ก GTM Signals Aggregator๐Ÿš€ Prospect Engine
๐Ÿ“ Publishing Frequency Tracker๐Ÿฆ‹ Bluesky Brand Presence Mapper
โฉ Sequencer Lead Push๐Ÿ”„ Company Change Event Feed
๐Ÿ“‡ Company Contact Details Extractor๐Ÿงญ Company Discovery List Builder
๐Ÿข Company Firmographic Enricher๐ŸŒ Company Social Presence Mapper
๐Ÿท๏ธ Contact Classifier๐Ÿ“ˆ Influencer Change Monitor
๐Ÿ”Ž Influencer Finder๐Ÿงพ Influencer Lead List Builder
๐Ÿ‘ค Influencer Profile Scraper๐Ÿ“ฌ Domain Deliverability Checker
๐Ÿ”— Domain to LinkedIn URL Resolver๐Ÿ›’ Ecommerce Platform Profiler
โœ‰๏ธ Work Email Waterfall๐ŸŽช Event Presence Index
โš–๏ธ Expert Witness Directory๐Ÿ’ต Company Funding Record
๐Ÿ’ฐ Funding and Press Signal Scanner๐Ÿ™ GitHub Organization Signal Scanner
๐Ÿง‘โ€๐Ÿ’ผ GTM Hiring Signal Scraper๐Ÿ“‹ Job Posting Monitor
๐Ÿงฑ Tech Stack Signal Detector๐ŸŽฏ ICP Fit Scorer
๐Ÿ”‘ Job Board Keyword Signal Scanner๐Ÿ›๏ธ Legal Entity Resolver
๐Ÿ“ฐ Link in Bio Scraper and Newsletter Detector๐Ÿ’ผ LinkedIn Company Page Mapper
๐Ÿ’ฌ LinkedIn Post Tracker๐Ÿ“ข Meta Ad Library Monitor
๐Ÿ“ธ Meta Brand Presence Mapper๐Ÿ“ฎ Outbound Stack Detector
๐Ÿ“„ Page Finder and Extractor๐Ÿง‘ People Finder & Email Verifier
๐Ÿ“Œ Pinterest Brand Presence Mapper๐Ÿ† Government Contract Award Monitor
๐Ÿ“… Reporting Window Finder๐Ÿ‘ฝ Reddit Brand Presence Mapper
โญ Trustpilot Reputation Enricher๐Ÿค Influencer Talent Agency Lookup
๐Ÿ‘ฅ Team Page People Extractor๐ŸŽต TikTok Brand Presence Mapper
๐Ÿ“Š Website Traffic Rank Estimator๐Ÿ… Workplace Program Detector
โœ–๏ธ X Brand Presence Mapperโ–ถ๏ธ YouTube Channel Stats Extractor

Every actor in the suite takes a domain or a company and returns one flat row, so they stack in the same Clay table without reshaping anything.

๐Ÿ› ๏ธ Need something custom built for you or your team? Tell us what you are trying to find and we will build it. Talk to Mamba Labs.

๐Ÿ†˜ Support

Something wrong, or a company the actor resolves incorrectly? Open an issue on the Issues tab with the inputs and the row, and we will look at it.

โ„น๏ธ Sourcing and legal. This actor uses public data only: DNS, the company's own homepage and its schema.org JSON-LD, and login-free public search (Brave, Bing, DuckDuckGo). No request to LinkedIn, no personal profiles, no paid third-party API. You are responsible for how you use the output.

โš–๏ธ Unofficial

This actor is unofficial. It is not affiliated with, sponsored by, or endorsed by LinkedIn, Microsoft, Bing, Brave or DuckDuckGo. It reads publicly available pages only, with no account and no authenticated session.

Built by Mamba Labs.