Credits + limits
Predictable cost, one budget per account, reruns never spend.
The unit
A scan costs ceil(span_days x symbols / 20000) units, computed from your validated document BEFORE the engine runs: span from the times.anchor_time bounds, symbols from your identity.symbol clause (the full universe of 847 when unscoped). A 30-day universe scan is 2 units; a full-history universe scan is ~18. The estimate and the charge are the same number - you can price a scan by reading your own document.
When you spend
A debit happens on exactly one path: HTTP 200 with X-Research-Cache: miss - the engine actually scanned. Everything else is free: cache hits (X-Research-Cache: hit), 304 revalidations against your ETag, validation failures, SCAN_BUSY, timeouts. Re-running a result never spends - determinism makes that enforceable, not a promise.
Every query response carries the meters: X-Research-Credits-Estimate, X-Research-Credits-Charged, X-Research-Credits-Remaining.
Budgets
| TIER | UNITS / MONTH (UTC) |
|---|---|
| Free | 5 |
| Pro | 100 |
One ledger per ACCOUNT: scans from the /research page and scans over the API draw the same budget. Interpretation (POST /interpret) is a free proposal step and never debits the scan allowance. An over-allowance scan answers 402 RESEARCH_ALLOWANCE_EXHAUSTED with your state in the body.
Concurrency + rate
| LIMIT | VALUE | ON HIT |
|---|---|---|
| In-flight scans per key | 1 | 429 SCAN_BUSY + Retry-After |
| Requests per key | 60 / minute | 429 RATE_LIMITED + Retry-After |
| Scan budget (engine) | 90 s | 504 SCAN_TIMEOUT |
The SCAN_BUSY dance
The engine bounds concurrent scans globally; under contention it queues your request up to 20 seconds, then answers 429 SCAN_BUSY with a Retry-After. Honor it, retry once or twice, and prefer re-running EXACT documents: identical documents share one flight and one cache entry, so a busy engine still serves your repeat for free the moment the first run lands.