Authentication

All public endpoints use a workspace API token:
  • GET routes require api.read
  • POST routes require api.write
  • 401 means the token is missing or invalid
  • 403 means the token is valid but lacks the required scope
The helper routes below are useful when you want to inspect the token context before running metered jobs:
  • GET /v1/public/token-info
  • GET /v1/public/tenant-info

Test keys

Keys come in two modes, and the key itself tells you which one you are holding: A test key is not a sandbox. It runs the same scrapers against the same live targets and returns the same responses, including the same failures — a stub that always succeeded would tell you nothing about whether this API works on your URLs, which is the only question an evaluation is asking. What differs is what it spends. Instead of draining credits, a test key draws on a per-organization allowance of 125 notional credits per rolling 24-hour window. Nothing is billed, and creditsCharged is 0 on every test job.
Create one in the dashboard under API tokens by choosing Test before you create the key. Mode is fixed at creation: a key cannot be switched later, which is what keeps a key that was audited as non-billable from quietly becoming billable.
The window is trailing, not calendar-aligned. Usage ages out continuously, so the allowance recovers gradually rather than resetting at a fixed hour — there is no midnight to wait for after an afternoon of testing.
When the allowance is spent, requests fail with 429 and error.code = "test_quota_exhausted":
Because test traffic never bills, test keys are the right credential for a CI suite: a build that runs the real API on every commit costs nothing and still fails when we break something you depend on. GET /v1/public/balance reports both positions, and names the mode of the key that asked, so a test key is never handed a balance it is not spending:

Credits

Search and scrape endpoints are metered. Credits are charged when a job is created — by a live key. A test key spends its allowance instead; everything below describes live keys.
  • A fresh successful job reports creditsCharged with the debit amount.
  • A cached hit reports creditsCharged: 0 and cached: true.
  • If the workspace does not have enough credits, the API returns 402 with error.code = "insufficient_credits".

Cache controls

All metered search and scrape requests accept the shared cache/job fields:
  • fresh: bypass cache and force a new fetch
  • cacheTtlSec: override the cache TTL written for the new result (capped at 7 days)
  • idempotencyKey: deduplicate repeated submissions
  • webhookUrl: receive a terminal callback instead of only polling

Sync wait defaults

The API defaults to synchronous behavior:
  • wait defaults to true
  • waitTimeoutMs can ask for a shorter timeout
  • the server still enforces its own maximum sync wait budget
If the result is not ready in time, the API returns 202 Accepted with a poll URL rather than holding the request open longer. Long-running kinds — research, linkedin/employees, and LinkedIn channel — always return 202 immediately regardless of wait: their minimum runtime is minutes, so a sync wait could never observe completion. Poll the job URL or use webhookUrl.