Skip to main content
Glama

batch_create

Submit a Batch job: many URLs scraped asynchronously in the cloud (Zenrows Batch API). Suited to large URL lists; scrape and extract handle single pages. Not the same as browser_batch.

Tasks use automatic mode (mode=auto) by default: Zenrows enables JS rendering and premium proxies only on the pages that need them. Pass just the URLs. Set js_render or premium_proxy (job-level, or per task) only to force a fixed configuration; that turns automatic mode off for those tasks.

Cost: the same credits as the regular API, per successful task: 1 for a basic request, 5 with js_render, 10 with premium_proxy, 25 with both; mode=auto bills each task at the configuration that worked. Failed tasks are not billed, except target 404 and 410 answers, billed as on the regular API. Limits: up to 100,000 tasks per call; 3 active jobs per account by default, shared with Crawl (BATCH_QUOTA_EXCEEDED past that); a job frees its slot when its run ends.

Creates a closed job with every task in this one call. Each task takes a url plus optional external_id, metadata, method/body (POST tasks) and scrape params. Every call sends an Idempotency-Key, so the bounded retries on network errors and 5xx never create a second job; an error reply carries the key to retry with.

Returns job_id, status and stats at once; the job runs asynchronously. Then: batch_wait until it ends, batch_results to list rows (paged), batch_content to read one task's page. A run that ends failed (out of credits, inactive subscription, key cap) answers ok:false with error.code and server_code; batch_rerun recovers it. Submits of 10,000+ tasks keep writing tasks for a while (ingesting:true). Errors: BATCH_INVALID_REQUEST (400, server_code and invalid_tasks say what), BATCH_INSUFFICIENT_CREDITS (402), BATCH_KEY_CAP_REACHED (402, this key's cap), BATCH_QUOTA_EXCEEDED (429, job limit), AUTH_INVALID (401; server_code subscription_inactive means fix Billing), BATCH_ACCESS_DENIED (403, do not retry), BACKEND_UNAVAILABLE. Schedules, webhooks, exports, CSV inputs and open jobs are available through the Batch API and SDKs only.

Input Schema

NameRequiredDescriptionDefault
urlsNoShorthand: list of URLs (converted to tasks), up to 100,000. Ignored when tasks is provided.
waitNoIf true, poll before returning until the run ends or pauses, or wait_timeout passes; a timeout returns the current state with ok:true
tasksNoTasks (each needs a url), up to 100,000. Prefer this over urls when you need per-task params.
js_renderNoForce js_render on all tasks (5 credits each). Overrides automatic mode (mode=auto), which already renders when needed.
mode_autoNoAutomatic mode (mode=auto) is on by default; leave unset. False sends plain requests without it.
wait_timeoutNoMax wait in seconds when wait=true (default 50). Many MCP clients cancel a call after 60 s.
premium_proxyNoForce premium_proxy on all tasks (10 credits each, 25 with js_render). Overrides automatic mode (mode=auto), which already uses premium proxies when a page needs them.
proxy_countryNoJob-level ISO country code. Works in automatic mode (mode=auto); with js_render alone it requires premium_proxy.
response_typeNoJob-level output format. Leave unset for the raw HTML, the default.
zenrows_paramsNoAdditional job-level scrape params merged with the flags above. Accepted: allowed_status_codes, autoparse, block_resources, css_extractor, custom_headers, extract, extract_fields, js_instructions, js_render, json_response, mode, original_status, outputs, premium_proxy, proxy_country, response_type, session_id, wait, wait_for.
idempotency_keyNoSent as the Idempotency-Key header, up to 128 characters; generated per call when unset. Reusing a key with the identical request within 24 hours returns the original response instead of doing it again; with a different request it is BATCH_IDEMPOTENCY_CONFLICT.
wait_timeout_msNoDeprecated: the same wait in milliseconds. Use the seconds parameter instead.

Schema Changelog

Changes observed during successful MCP inspections.

  1. Changed14 schema fields changed
    • addedInput schema / properties / idempotency_key
      Added value: +{
      +  "anyOf": [
      +    {
      +      "maxLength": 128,
      +      "minLength": 1,
      +      "type": "string"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Sent as the Idempotency-Key header, up to 128 characters; generated per call when unset. Reusing a key with the identical request within 24 hours returns the original response instead of doing it again; with a different request it is BATCH_IDEMPOTENCY_CONFLICT."
      +}
    • changedInput schema / properties / js_render / description
      Previous value: -"Force js_render on all tasks. Overrides automatic mode (mode=auto), which already renders when needed."New value: +"Force js_render on all tasks (5 credits each). Overrides automatic mode (mode=auto), which already renders when needed."
    • changedInput schema / properties / premium_proxy / description
      Previous value: -"Force premium_proxy on all tasks (10x cost). Overrides automatic mode (mode=auto), which already uses premium proxies when a page needs them."New value: +"Force premium_proxy on all tasks (10 credits each, 25 with js_render). Overrides automatic mode (mode=auto), which already uses premium proxies when a page needs them."
    • changedInput schema / properties / response_type / anyOf
      Previous value: -[
      -  {
      -    "enum": [
      -      "markdown",
      -      "plaintext",
      -      "html",
      -      "pdf"
      -    ],
      -    "type": "string"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "enum": [
      +      "markdown",
      +      "plaintext",
      +      "pdf"
      +    ],
      +    "type": "string"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / response_type / description
      Previous value: -"Job-level response_type"New value: +"Job-level output format. Leave unset for the raw HTML, the default."
    • changedInput schema / properties / tasks / anyOf
      Previous value: -[
      -  {
      -    "items": {
      -      "additionalProperties": false,
      -      "properties": {
      -        "external_id": {
      -          "description": "Optional stable id echoed back on results",
      -          "type": [
      -            "string",
      -            "null"
      -          ]
      -        },
      -        "metadata": {
      -          "anyOf": [
      -            {},
      -            {
      -              "type": "null"
      -            }
      -          ],
      -          "description": "Opaque per-task metadata carried through to results"
      -        },
      -        "url": {
      -          "description": "Target URL for this task",
      -          "format": "uri",
      -          "type": "string"
      -        },
      -        "zenrows_params": {
      -          "anyOf": [
      -            {
      -              "additionalProperties": {
      -                "type": [
      -                  "string",
      -                  "number",
      -                  "boolean"
      -                ]
      -              },
      -              "type": "object"
      -            },
      -            {
      -              "type": "null"
      -            }
      -          ],
      -          "description": "Per-task Zenrows scrape params (js_render, premium_proxy, extract, autoparse, …)"
      -        }
      -      },
      -      "required": [
      -        "url"
      -      ],
      -      "type": "object"
      -    },
      -    "type": "array"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "items": {
      +      "additionalProperties": true,
      +      "description": "A task. Scrape params may go in zenrows_params or flat on the task (e.g. extract, js_render); a flat key wins over the same key in zenrows_params.",
      +      "properties": {
      +        "body": {
      +          "description": "Request body, only with method POST, up to 16 KiB. An object or array is sent as JSON; a string is sent as is, form encoded."
      +        },
      +        "external_id": {
      +          "anyOf": [
      +            {
      +              "maxLength": 128,
      +              "pattern": "^[A-Za-z0-9._-]+$",
      +              "type": "string"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "description": "Optional id of your own, echoed back on results: up to 128 characters, letters, digits, '.', '_' and '-' only (no spaces). Need not be unique. Put free text in metadata instead."
      +        },
      +        "metadata": {
      +          "anyOf": [
      +            {
      +              "additionalProperties": {
      +                "maxLength": 1024,
      +                "type": "string"
      +              },
      +              "propertyNames": {
      +                "maxLength": 64,
      +                "minLength": 1,
      +                "pattern": "^[A-Za-z0-9._-]+$"
      +              },
      +              "type": "object"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "description": "Optional string-to-string map echoed back on results: up to 20 entries; keys 1 to 64 characters of letters, digits, '.', '_' and '-'; values up to 1,024 characters; 4 KiB in all. Values must be strings: convert numbers and booleans first."
      +        },
      +        "method": {
      +          "anyOf": [
      +            {
      +              "enum": [
      +                "GET",
      +                "POST"
      +              ],
      +              "type": "string"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "description": "HTTP method for this task (default GET). POST is for read-only queries such as search or GraphQL endpoints: the target can receive the same POST more than once. POST cannot be combined with js_render, js_instructions or json_response."
      +        },
      +        "url": {
      +          "description": "Target URL for this task: http or https, up to 2,048 characters",
      +          "format": "uri",
      +          "maxLength": 2048,
      +          "type": "string"
      +        },
      +        "zenrows_params": {
      +          "anyOf": [
      +            {
      +              "additionalProperties": {
      +                "type": [
      +                  "string",
      +                  "number",
      +                  "boolean"
      +                ]
      +              },
      +              "type": "object"
      +            },
      +            {
      +              "type": "null"
      +            }
      +          ],
      +          "description": "Per-task scrape params, over the job's. Accepted: allowed_status_codes, autoparse, block_resources, css_extractor, custom_headers, extract, extract_fields, js_instructions, js_render, json_response, mode, original_status, outputs, premium_proxy, proxy_country, response_type, session_id, wait, wait_for. Booleans as true/false. Screenshot params are not supported in Batch."
      +        }
      +      },
      +      "required": [
      +        "url"
      +      ],
      +      "type": "object"
      +    },
      +    "maxItems": 100000,
      +    "type": "array"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / tasks / description
      Previous value: -"List of tasks (each needs a url). Prefer this over urls when you need per-task params."New value: +"Tasks (each needs a url), up to 100,000. Prefer this over urls when you need per-task params."
    • changedInput schema / properties / urls / anyOf
      Previous value: -[
      -  {
      -    "items": {
      -      "format": "uri",
      -      "type": "string"
      -    },
      -    "type": "array"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "items": {
      +      "format": "uri",
      +      "maxLength": 2048,
      +      "type": "string"
      +    },
      +    "maxItems": 100000,
      +    "type": "array"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / urls / description
      Previous value: -"Shorthand: list of URLs (converted to tasks). Ignored when tasks is provided."New value: +"Shorthand: list of URLs (converted to tasks), up to 100,000. Ignored when tasks is provided."
    • changedInput schema / properties / wait / description
      Previous value: -"If true, poll until the job reaches a terminal state before returning"New value: +"If true, poll before returning until the run ends or pauses, or wait_timeout passes; a timeout returns the current state with ok:true"
    • addedInput schema / properties / wait_timeout
      Added value: +{
      +  "anyOf": [
      +    {
      +      "maximum": 3600,
      +      "minimum": 1,
      +      "type": "integer"
      +    },
      +    {
      +      "type": "null"
      +    }
      +  ],
      +  "description": "Max wait in seconds when wait=true (default 50). Many MCP clients cancel a call after 60 s."
      +}
    • changedInput schema / properties / wait_timeout_ms / description
      Previous value: -"Max wait time when wait=true (default 600000)"New value: +"Deprecated: the same wait in milliseconds. Use the seconds parameter instead."
    • changedInput schema / properties / zenrows_params / anyOf
      Previous value: -[
      -  {
      -    "additionalProperties": {
      -      "type": [
      -        "string",
      -        "number",
      -        "boolean"
      -      ]
      -    },
      -    "type": "object"
      -  },
      -  {
      -    "type": "null"
      -  }
      -]New value: +[
      +  {
      +    "$ref": "#/properties/tasks/anyOf/0/items/properties/zenrows_params/anyOf/0"
      +  },
      +  {
      +    "type": "null"
      +  }
      +]
    • changedInput schema / properties / zenrows_params / description
      Previous value: -"Additional job-level zenrows_params merged with the flags above"New value: +"Additional job-level scrape params merged with the flags above. Accepted: allowed_status_codes, autoparse, block_resources, css_extractor, custom_headers, extract, extract_fields, js_instructions, js_render, json_response, mode, original_status, outputs, premium_proxy, proxy_country, response_type, session_id, wait, wait_for."
  2. First observed

TDQS

A4.6/5.0
Behavior5/5

Does the description disclose side effects, auth requirements, rate limits, or destructive behavior?

With annotations only covering write/open-world/safe profile, the description carries real behavioral weight: credit costs per configuration (1/5/10/25), billing rules for failed and 404/410 tasks, hard limits (100,000 tasks, 3 active jobs, BATCH_QUOTA_EXCEEDED), idempotency guarantees across retries, and the full error taxonomy with actionable codes. This is substantially beyond what readOnlyHint/destructiveHint/openWorldHint convey.

Agents need to know what a tool does to the world before calling it. Descriptions should go beyond structured annotations to explain consequences.

Conciseness4/5

Is the description appropriately sized, front-loaded, and free of redundancy?

Front-loaded and organized into labeled paragraphs (purpose, mode, cost, limits, returns/workflow, errors), so a reader can stop after the first two sentences. It is long, and the exhaustive error-code enumeration plus the cost paragraph border on verbosity for a tool-selection read, but each block is distinct and non-redundant.

Shorter descriptions cost fewer tokens and are easier for agents to parse. Every sentence should earn its place.

Completeness5/5

Given the tool's complexity, does the description cover enough for an agent to succeed on first attempt?

There is no output schema, and the description compensates fully: it states what is returned (job_id, status, stats), that the job runs asynchronously, the ok:false/error.code/server_code failure shape, the ingesting:true behavior for 10,000+ task submits, and the exact follow-up toolchain. For a 12-parameter, 0-required async job creator, nothing an agent needs is missing.

Complex tools with many parameters or behaviors need more documentation. Simple tools need less. This dimension scales expectations accordingly.

Parameters3/5

Does the description clarify parameter syntax, constraints, interactions, or defaults beyond what the schema provides?

Schema description coverage is 100%, and the schema itself already documents credits per flag, mode=auto default, idempotency-key reuse semantics, and the urls-vs-tasks precedence. The description's prose on 'Pass just the URLs' and 'Set js_render ... only to force a fixed configuration' largely restates that, so the baseline of 3 for a fully-covered schema is the correct ceiling.

Input schemas describe structure but not intent. Descriptions should explain non-obvious parameter relationships and valid value ranges.

Purpose5/5

Does the description clearly state what the tool does and how it differs from similar tools?

The opening sentence names the verb and resource precisely ('Submit a Batch job: many URLs scraped asynchronously in the cloud') and immediately positions it against siblings, stating that 'scrape and extract handle single pages' and 'Not the same as browser_batch.' An agent can tell exactly what this does and what it does not, without opening a schema.

Agents choose between tools based on descriptions. A clear purpose with a specific verb and resource helps agents select the right tool.

Usage Guidelines5/5

Does the description explain when to use this tool, when not to, or what alternatives exist?

It gives an explicit selection rule ('Suited to large URL lists; scrape and extract handle single pages'), rules out a lookalike sibling ('Not the same as browser_batch'), and names the follow-up tools in sequence (batch_wait, batch_results, batch_content, batch_rerun). It even states what is out of scope (schedules, webhooks, exports, CSV inputs, open jobs are API/SDK-only).

Agents often have multiple tools that could apply. Explicit usage guidance like "use X instead of Y when Z" prevents misuse.

Try in Browser

Glama MCP Gateway

Add one secure layer between your agents and this server.