Create a job
POST /api/v1/jobs/create/ with a scraper_type and its input in config:
The answer is
201 with the job. The price is locked at this moment, and the job’s credit is checked. A request is
refused with 402 if the balance can’t cover its estimate, or if that estimate plus the quoted estimated_cost
of the organization’s pending and running jobs exceeds 10 times the balance (Billing).
A 402 creates no job, so retrying the request after backing off is safe.
How config is checked:
- A field the scraper doesn’t know is ignored, not refused. Check spelling and case: a misspelt limit runs with the default.
- An input a scraper accepts but can’t act on with the value you sent is ignored too. Each guide lists them.
- Either way the job still runs, and its log (
GET /api/v1/jobs/{id}/logs/) gets oneWARNINGnaming the fields, for exampleInput(s) limitt are not recognised for instagram and had no effect; check the spelling. - An empty list (
"usernames": []) is refused with400. - Numbers, links and dates the scraper guide gives a range for are checked, and a value outside it is refused with
400naming the field.
Statuses
Wait on
is_terminal, not on status. A job that fails while it still has automatic retries left reads
"status": "failed" with "is_terminal": false and "will_auto_retry": true: it is about to run again, under the
same id. is_terminal is true once the job is completed or cancelled, or failed or timed_out with no retry
coming. The SDK’s call() and wait_for_finish() already wait for it.
Each earlier attempt is listed in attempt_history with its status, error_message and failed_at.
error_code
A job that did not complete has an error_code, so your code can decide what to do without reading
error_message:
A finished job
A real completed job, from a test run of the quickstart on a local stack. Amounts are shown as"…": rates
change, so the docs leave them out.
Read the results
GET /api/v1/jobs/{id}/results/?offset=0&limit=100 returns a page of rows:
limitis 50 by default and at most 100. Page withoffsetuntil you havetotalrows, or a page comes back withcount0.totalincludes $0 status rows, such as Instagram’sprofile_error, so it can exceeditems_scraped.- A running job already returns the rows delivered so far.
- Each row is the scraper’s own record. Its fields are in the scraper’s guide.
- Rows don’t always come back in input order. Match them to your input with the field the guide names (
input,facebookUrl,search_term, …).
iterate_items() pages for you:
Is it complete?
completed means the job ran to its end. It does not always mean every target delivered everything: a private
account, a page that shows nothing to signed-out visitors, or a platform that stopped answering partway leaves gaps.
scraper_metadata says what happened, with keys that depend on the scraper:
Each scraper guide lists what it reports.
Logs, cancel and retry
Lists and paging
Every list answers{"total", "offset", "limit", "count", "results"}. Page with offset and limit: 25 rows by
default, at most 100. The audit log is the exception: it pages with page and page_size (100 by default) and
answers {"count", "next", "previous", "results"}.