Skip to main content
A streaming plan, a phone and a software subscription cost different amounts in Tokyo, Istanbul and Oslo, and the only way to see the local price is to visit the site from that country. By hand that is twenty VPN hops, four sites each, and a spreadsheet of currencies. This program sends one agent per country, each browsing from a profile pinned to that country, and turns their structured answers into one table in US dollars.

What you need

  • An Outcrawl API key in OUTCRAWL_API_KEY.
  • A plan with enough browsers for the lanes you choose: 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, and an agent run holds its slot until it ends. The program runs 4 at a time, which fits Builder.
  • Node 18 or later for TypeScript, or Python 3.10 or later. Exchange rates come from the free, keyless Frankfurter API (ECB reference rates).

How it works

1

One profile per country

Profiles are created once with an exit country and reused on every run. The browser’s IP, timezone and language follow that exit, so each site serves its local store. Cookie banners dismissed on the first run stay dismissed.
2

One agent per country, with a schema

Each agent run gets the same four items and a JSON Schema. The run is judged against the schema, and run.data comes back in that shape: item, price, currency, billing period, source URL.
3

A fixed number of lanes, retried on refusal

Over your account’s browser count, a submit is refused with ConcurrencyLimitError, never queued. The program runs 4 lanes, waits 20 seconds and retries a refused submit, and waits the stated retryAfterSeconds on a per-minute QuotaExceededError. See errors.
4

A ceiling for the whole batch

Each run has a hard caps.budget. Before a run starts, the program reserves that budget against a batch ceiling and releases it to the real cost when the run ends, so the batch cannot start a run it could not afford.
5

One table

The program converts every local price to US dollars at today’s reference rate, prints a table and writes basket-prices.json.

The program

A refusal arrives on the submit, before any run exists, so the retry wraps the submit and nothing else. A retry never starts a second run for the same country. Once a run exists it holds its slot until it ends, and the lane waits for it.

What you get back

The printed table (rows shortened, prices illustrative):
And basket-prices.json, one row per country in the schema’s shape:
A country the fleet has no exit for, or a run that hit its cap, comes back with problem set and no prices. The rest of the table is unaffected.

What it costs

An agent run is billed for the model’s usage, browser time and proxy usage (pricing). A typical run costs about 15 credits a minute all in, proxy usage included; the real figure depends on the task, and a page-heavy site costs more.
  • One country: about 2 minutes across the four sites, so about 30 credits.
  • Twenty countries: about 600 credits, which the batch ceiling of 1,500 bounds.
  • Wall clock: 20 runs over 4 lanes is 5 rounds of about 2 minutes, so about 10 minutes. With 20 lanes on Pro it is one round.

Make it yours

  • Swap the basket for flights, hotel nights or car rentals, and add a date field to the schema.
  • Pin a city, not only a country: exit: { country: 'us', region: 'texas', city: 'austin' }.
  • Run it weekly and diff basket-prices.json against last week’s to catch a price change in one market.
  • Set LANES from your plan: 4 on Builder, 20 on Pro, 90 on Scale, always below the plan’s count.

Agents

Tasks, caps, schemas and what a run returns.

Profiles

Saved logins and a pinned geography, reused across runs.

Rules

Plain-language limits the run is held to.

Errors

What concurrency_limit and quota_exceeded mean, and which are retryable.