Skip to main content
A list of 500 target accounts is worth little until someone knows what each company sells, what it charges, who runs it and whether it is growing. A researcher gets through perhaps twenty a day. This program runs the whole list in lanes: a search for recent news, a crawl of the company’s own pages with structured extraction, and an agent only for what the crawl could not find. It dedupes by domain and writes every profile into HubSpot.

What you need

  • An Outcrawl API key in OUTCRAWL_API_KEY.
  • companies.csv with a header row and name,domain per line: a CRM export, a conference attendee list, a portfolio page.
  • A HubSpot private app token in HUBSPOT_TOKEN with the crm.objects.companies.read and crm.objects.companies.write scopes, and five text properties created once on the company object: pricing_summary, decision_makers, open_roles, team_size_signal, recent_news. The HubSpot calls are your own code, plain HTTPS.
  • A plan with enough browsers for your lanes: Free 2, Builder 5, Pro 25, Scale 100. Every key on your account shares one browser slot count. Browsers, agent runs, crawls, searches and scrapes that aren’t served from cache each hold a slot.

How it works

1

Search for the signal

One search per company for funding, hiring and layoff news. Five results, titles and links only, which is 2.5 credits.
2

Crawl the company's own pages

A crawl of up to 8 pages, limited to about, team, pricing and careers paths, with formats: ['json'] and a schema. Every page comes back as the facts it holds: what they do, plans and prices, named people, open roles, team size.
3

An agent for the gaps

If the crawl found no prices or no leaders, an agent visits the site to find them: it switches a monthly or yearly toggle, or opens a team page that loads as you scroll. An enforced rule keeps it on the company’s own domain, and a second tells it not to submit a form, book a demo, start a trial or sign in.
4

Lanes, retries and a ceiling

Four lanes, each holding at most one slot. A refused call (ConcurrencyLimitError, or QuotaExceededError on requests per minute) waits and retries: 20 seconds for a slot, or the retryAfterSeconds the error names. Running out of monthly credits stops. Every step reserves its maximum cost against a batch ceiling before it starts.
5

Deduplicate and write

Domains are normalised before anything runs, so www.acme.com and https://acme.com/ are one company. People are deduplicated by name. Each profile updates the HubSpot company with that domain, or creates it.

The program

The retry wraps only the call that can be refused. A crawl or search that is refused never started, so retrying it cannot bill twice, and an agent run is retried at its submit, never after it exists. A company whose steps fail keeps whatever the earlier steps found.

What you get back

One entry per unique domain in companies.json, and the same fields on the HubSpot company record:
And the last line printed:

What it costs

Rates from pricing: search 5 credits per 10 results, crawl 1 credit a page. An agent run is billed for the model’s usage, browser time and proxy usage, and a typical run costs about 15 credits a minute all in, proxy usage included. That is an estimate: the real figure depends on the task, and a page-heavy site costs more.
  • Search: 5 results, 2.5 credits a company.
  • Crawl: at most 8 pages, up to 8 credits a company.
  • Agent: needed for about a third of companies, at about 60 s, so about 15 credits a run, or about 5 credits averaged over the list.
  • Per company, about 15.5 credits. For 500 companies, about 7,750 credits, under the 10,000 ceiling. Pro’s 50,000 monthly credits covers it about six times.
  • Wall clock: about a minute a company, so 500 over 4 lanes is about two hours. On Pro with 20 lanes it is about 25 minutes.

Make it yours

  • Build the list from search instead of a CSV: take the domain of every hit for "Series A" developer tools Berlin.
  • Write to Salesforce, Attio or a Postgres table instead: only step 4 changes.
  • Add fields to PAGE_SCHEMA, such as the tech stack named on the careers pages or the customer logos on the home page.
  • Re-run monthly and write only the fields that changed, so your team sees a pricing change as a HubSpot property history entry.

Search

Results for a query, optionally rendered.

Crawl

Walk a site, stream every page with structured output.

Agents

Tasks, caps, schemas and what a run returns.

Errors

What concurrency_limit and quota_exceeded mean, and which are retryable.