Skip to content

Pricing & quotas

Every scrape spends credits from a monthly pool tied to your plan. Each plan also caps how many scrapes you can run at once. Both limits are enforced on the /scrape (and /map) hot path.

Cost is charged per URL, keyed by the engine you request (a multi-URL request costs the sum). The weights track real infrastructure cost — a plain fetch is the floor, an AI exploration pass adds model tokens, and a Chromium session is the expensive part.

EngineCredits / URL
html1
ai-html3
browser5
ai5
ai-browser10

ai auto-resolves to the html or browser runner at request time, but that’s unknown when we charge, so it’s priced at the browser tier — it’s not a cheap path to a browser run. Caching a generated AI plan and POSTing it back as deterministic actions drops the per-run cost to the underlying engine’s rate (1 or 5).

credits is the monthly pool (reset at the start of each UTC month, no rollover); concurrency caps simultaneous in-flight scrapes per user. New accounts start on free.

PlanPrice / moMonthly creditsConcurrency
free$01,0002
starter$4925,0005
growth$149150,00015
scale$499750,00040

Manage your subscription on the billing page. The same catalog is available programmatically at GET /billing/plans.

GET /usage (Clerk-authenticated, like the rest of /me/*) returns the current period’s quota state:

{
plan: 'free' | 'starter' | 'growth' | 'scale';
period: string; // UTC "YYYY-MM"
creditsLimit: number;
creditsUsed: number;
creditsRemaining: number;
concurrencyLimit: number;
}

The dashboard’s billing page is a visual wrapper over this.

StatusBodyCause
402{ "error": "credit quota exceeded", "creditsLimit", "creditsUsed", "creditsRemaining": 0 }The request would exceed your monthly credit pool. Upgrade your plan or wait for the next period.
429{ "error": "concurrency limit exceeded", "concurrencyLimit" }Too many scrapes already in flight for your account. A Retry-After: 5 header is set — back off and retry.