Skip to main content
When URLs arrive over time, from a crawler, a message queue or a nightly export that lands in pieces, open a Batch job first and feed it as you go. Zenrows starts scraping the first URLs right away, keeps accepting new ones, and finishes the run once you close the job. One job, one set of results, no matter how many groups you send. Uses: Batch open jobs ("status": "open", POST /jobs/{id}/tasks, last_batch, POST /jobs/{id}/close)

Ask your AI agent

Paste this prompt into a coding agent such as Claude Code or Cursor, with the Zenrows docs connected. The agent looks up the details and writes the calls.

Open a job and stream URLs into it

  1. Create the job with "status": "open". Tasks are optional at this point. The zenrows_params you set here apply to every URL you add later.
  2. Send each group of URLs to POST /jobs/{job_id}/tasks as {"tasks": [...]}. Scraping starts with the first group.
  3. Close the job when your producer is done: either send the last group with "last_batch": true, or call POST /jobs/{job_id}/close. The run then finishes the queued tasks and ends completed.
Read the results like any other job, see Scrape a list of URLs or Download all results of a job at once.

Example output

The Python run:
The response to the last cURL call, with "last_batch": true:

Use the Python SDK

submit_open opens the job, add_tasks appends a group, and "last_batch": True on the final group closes it. job.close() does the same without adding tasks.
Python (SDK)
Output

Customize it

Troubleshooting

  • Adding tasks returns 409 with job_not_open: the job is already closed by last_batch or /close. Open a new job for the next set of URLs.
  • Adding tasks right after a large submission returns 409: the job is still ingesting the previous group. Wait a few seconds and send the group again.
  • The run stays running after your producer finishes: the job is still open. Call POST /jobs/{job_id}/close so the run can complete.
  • 429 with too_many_crawls: other Crawl and Batch jobs on your account are still running. Wait the number of seconds in the Retry-After header, then open the job.

Scrape a list of URLs

Send every URL up front as one job.

Start a Batch job from a CSV file

Upload a whole CSV of URLs at once.

Use different settings for each URL in one job

Give one task markdown, another JSON fields.

Get notified when a Batch job finishes

Receive a webhook instead of polling.