{
  "openapi": "3.1.0",
  "info": {
    "title": "Zenrows API",
    "version": "1.0.0",
    "summary": "Reach any page, including the protected web, and return it as HTML, Markdown, plaintext, PDF or structured JSON.",
    "description": "Zenrows is web data infrastructure for agents and applications. Two HTTP surfaces are described here:\n\n- **Fetch and Extract** — one synchronous request per page, at `https://api.zenrows.com/v1/`. Authentication is the `apikey` query parameter.\n- **Batch** — asynchronous jobs of up to 100,000 URLs, at `https://async.api.zenrows.com/v1`. Authentication is the `X-API-Key` header.\n\n**Browser Sessions** is not described here because it is not HTTP: you connect Puppeteer or Playwright to a WebSocket endpoint. See https://docs.zenrows.com/browser-sessions.\n\n**Cost.** A request costs 1 credit, 5 with JavaScript rendering, 10 with premium proxies, 25 with both, and 1 to 25 under `mode=auto`. Failed requests are never charged. The free tier is 5,000 credits a month, no card.\n\n**Getting a key without a human.** `POST https://app.zenrows.com/api/agent/signup` returns a usable key; the spec is at https://www.zenrows.com/auth.md and a setup playbook at https://www.zenrows.com/SKILL.md.",
    "termsOfService": "https://www.zenrows.com/legal/terms-of-use",
    "contact": {
      "name": "Zenrows support",
      "email": "support@zenrows.com",
      "url": "https://www.zenrows.com/contact"
    },
    "license": {
      "name": "Proprietary",
      "url": "https://www.zenrows.com/legal/terms-of-use"
    }
  },
  "externalDocs": {
    "description": "Zenrows documentation",
    "url": "https://docs.zenrows.com"
  },
  "servers": [
    {
      "url": "https://api.zenrows.com/v1",
      "description": "Fetch and Extract (synchronous)"
    }
  ],
  "tags": [
    {
      "name": "Fetch",
      "description": "Retrieve one page, optionally rendered, proxied, converted or extracted."
    },
    {
      "name": "Batch",
      "description": "Submit many URLs as one job and collect the results."
    },
    {
      "name": "Account",
      "description": "Plan, credits and concurrency for the calling key."
    },
    {
      "name": "Onboarding",
      "description": "Get a working key with no human in the loop."
    }
  ],
  "security": [
    {
      "apiKeyQuery": []
    }
  ],
  "paths": {
    "/": {
      "get": {
        "operationId": "fetchPage",
        "summary": "Fetch a page",
        "description": "Retrieve a URL through Zenrows and return its content. The same operation covers Extract (`extract=auto` or `css_extractor`), format conversion (`response_type`), screenshots and structured output, because they are configurations of one request rather than separate endpoints.",
        "tags": [
          "Fetch"
        ],
        "parameters": [
          {
            "name": "apikey",
            "in": "query",
            "description": "Your Zenrows API key. Get one free at https://app.zenrows.com/register.",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "url",
            "in": "query",
            "description": "The URL of the page to retrieve.",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uri"
            },
            "example": "https://www.scrapingcourse.com/ecommerce/"
          },
          {
            "name": "mode",
            "in": "query",
            "description": "Adaptive Stealth Mode. `auto` starts from the cheapest viable configuration and escalates to JavaScript rendering or premium proxies only when the target requires it. You are billed for the configuration that succeeds.",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "auto"
              ]
            }
          },
          {
            "name": "js_render",
            "in": "query",
            "description": "Render the page in a headless browser before returning it. Required for content that only exists after JavaScript runs.",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "js_instructions",
            "in": "query",
            "description": "JSON array of browser instructions (click, fill, scroll, wait) executed on the page before the content is returned. Requires js_render.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "custom_headers",
            "in": "query",
            "description": "Forward your own request headers (cookies, referer) to the target.",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "premium_proxy",
            "in": "query",
            "description": "Route the request through residential IPs. Required by most protected sites.",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "proxy_country",
            "in": "query",
            "description": "Two-letter country code for the exit IP. Requires premium_proxy.",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[a-z]{2}$"
            },
            "example": "us"
          },
          {
            "name": "session_id",
            "in": "query",
            "description": "Reuse the same IP across requests for up to 10 minutes. Any integer you choose identifies the session.",
            "required": false,
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "original_status",
            "in": "query",
            "description": "Return the target's own HTTP status code instead of the Zenrows one.",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "allowed_status_codes",
            "in": "query",
            "description": "Comma-separated status codes whose body should be returned instead of raising an error, for example `404,500`.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "wait_for",
            "in": "query",
            "description": "CSS selector to wait for before returning. Requires js_render.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "wait",
            "in": "query",
            "description": "Milliseconds to wait after load before returning. Requires js_render.",
            "required": false,
            "schema": {
              "type": "integer",
              "default": 0,
              "minimum": 0
            }
          },
          {
            "name": "block_resources",
            "in": "query",
            "description": "Comma-separated resource types to block (for example `image,media,font`). Blocking is on by default.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "json_response",
            "in": "query",
            "description": "Return a JSON envelope that also carries the network requests (XHR/fetch) the page made.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "css_extractor",
            "in": "query",
            "description": "JSON object mapping output keys to CSS selectors, applied to the retrieved page.",
            "required": false,
            "schema": {
              "type": "string"
            },
            "example": "{\"title\":\"h1\",\"price\":\".price\"}"
          },
          {
            "name": "extract",
            "in": "query",
            "description": "Return structured JSON extracted from the page with no selectors to write (Extract). Accepted value: `auto`.",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "auto"
              ]
            }
          },
          {
            "name": "autoparse",
            "in": "query",
            "description": "Return the site's structured data where Zenrows knows the layout.",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "response_type",
            "in": "query",
            "description": "Convert the page before returning it: Markdown, plaintext or PDF.",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "markdown",
                "plaintext",
                "pdf"
              ]
            }
          },
          {
            "name": "screenshot",
            "in": "query",
            "description": "Return an above-the-fold screenshot of the page. Requires js_render.",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "screenshot_fullpage",
            "in": "query",
            "description": "Return a full-page screenshot. Requires js_render.",
            "required": false,
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "screenshot_selector",
            "in": "query",
            "description": "Screenshot only the element matching this CSS selector. Requires js_render.",
            "required": false,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "screenshot_format",
            "in": "query",
            "description": "Screenshot image format.",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "png",
                "jpeg"
              ],
              "default": "png"
            }
          },
          {
            "name": "screenshot_quality",
            "in": "query",
            "description": "JPEG quality, 1 to 100. Only with screenshot_format=jpeg.",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "outputs",
            "in": "query",
            "description": "Comma-separated data types to pull out of the retrieved HTML (for example `emails,phone_numbers`).",
            "required": false,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The target's content, in the shape the request asked for: HTML by default, Markdown or plaintext with `response_type`, a PDF or PNG/JPEG binary for `response_type=pdf` and the screenshot parameters, and JSON for `extract`, `css_extractor`, `autoparse` or `json_response`.",
            "content": {
              "text/html": {
                "schema": {
                  "type": "string",
                  "description": "The page as returned by the target."
                }
              },
              "text/markdown": {
                "schema": {
                  "type": "string",
                  "description": "The page converted to Markdown."
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string",
                  "description": "The page as plaintext."
                }
              },
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Structured output: the extracted fields, the autoparsed record, or the JSON envelope with captured network requests.",
                  "additionalProperties": true
                }
              },
              "application/pdf": {
                "schema": {
                  "type": "string",
                  "format": "binary",
                  "description": "The page rendered to PDF."
                }
              },
              "image/png": {
                "schema": {
                  "type": "string",
                  "format": "binary",
                  "description": "Screenshot of the page or of the selected element."
                }
              }
            },
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            }
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/agent/signup": {
      "post": {
        "operationId": "createAgentAccount",
        "summary": "Create an account and get a key, with no human",
        "description": "Create a trial account and return a usable API key in one unauthenticated request. No email, no password, no card, no form: an agent that has found this description can be calling the API on the next line. The account is unclaimed, and `claimUrl` is what a person opens later to take ownership of it.\n\nContract published at https://app.zenrows.com/agent-onboarding/auth.md, and advertised as `agent_auth.signup_endpoint` in https://app.zenrows.com/.well-known/oauth-protected-resource.",
        "tags": [
          "Onboarding"
        ],
        "servers": [
          {
            "url": "https://app.zenrows.com",
            "description": "Dashboard host, which serves the agent onboarding surface"
          }
        ],
        "security": [],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "No fields are required. An empty body is the normal call.",
                "additionalProperties": false
              }
            }
          }
        },
        "parameters": [
          {
            "name": "X-ZR-Agent-Id",
            "in": "header",
            "required": false,
            "description": "Optional provenance, anonymous and free of personal data.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-ZR-Client",
            "in": "header",
            "required": false,
            "description": "Optional name of the calling client.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-ZR-Source",
            "in": "header",
            "required": false,
            "description": "Optional origin of the signup.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "201": {
            "description": "The account exists and the key works immediately.",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "apiKey",
                    "accountId",
                    "claimUrl",
                    "trialEndsAt"
                  ],
                  "properties": {
                    "apiKey": {
                      "type": "string",
                      "description": "Pass it as the `apikey` query parameter to Fetch, or as `X-API-Key` to Batch."
                    },
                    "accountId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "claimUrl": {
                      "type": "string",
                      "format": "uri",
                      "description": "Where a person claims this account. Surface it to a human; do not sit on it."
                    },
                    "trialEndsAt": {
                      "type": "string",
                      "format": "date-time",
                      "description": "When the trial allowance stops."
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Error `rate_limited`: three signups per client IP per 24 hours. Wait; do not go looking for another signup URL.",
            "headers": {
              "RateLimit-Policy": {
                "$ref": "#/components/headers/RateLimitPolicy"
              },
              "RateLimit": {
                "$ref": "#/components/headers/RateLimit"
              },
              "Retry-After": {
                "$ref": "#/components/headers/RetryAfter"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SignupError"
                }
              }
            }
          },
          "500": {
            "description": "Error `signup_failed`. Retry once with backoff, then hand it to a human.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SignupError"
                }
              }
            }
          },
          "503": {
            "description": "Error `signup_disabled`: the kill switch is on. Retry later, and do not invent another signup URL.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SignupError"
                }
              }
            }
          }
        }
      }
    },
    "/api/agent/account": {
      "get": {
        "operationId": "getAgentAccount",
        "summary": "Check whether a person has claimed this account",
        "description": "Report the claim state of an account created by createAgentAccount. Claiming does not rotate the key, so an agent keeps working across it; this is how it learns a human took ownership. Never contains an email or any secret.",
        "tags": [
          "Onboarding"
        ],
        "servers": [
          {
            "url": "https://app.zenrows.com",
            "description": "Dashboard host, which serves the agent onboarding surface"
          }
        ],
        "security": [
          {
            "apiKeyHeader": []
          }
        ],
        "responses": {
          "200": {
            "description": "The account and its claim state.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "accountId",
                    "claimed",
                    "isAgent"
                  ],
                  "properties": {
                    "accountId": {
                      "type": "string",
                      "format": "uuid"
                    },
                    "claimed": {
                      "type": "boolean",
                      "description": "Whether a person has taken ownership."
                    },
                    "isAgent": {
                      "type": "boolean",
                      "description": "Whether the account was created by the agent signup."
                    },
                    "trialEndsAt": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "format": "date-time"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Error `invalid_key`: the key is missing or unknown.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SignupError"
                }
              }
            }
          }
        }
      }
    },
    "/subscriptions/self/details": {
      "get": {
        "operationId": "getSubscriptionDetails",
        "summary": "Read the plan behind the key",
        "description": "Return the calling key's plan: credit allowance, credits used, and the concurrency it is allowed. Use it to budget before a large run.",
        "tags": [
          "Account"
        ],
        "responses": {
          "200": {
            "description": "Plan, credit and concurrency figures for the calling key.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Documented at https://docs.zenrows.com/batch/developer-guide-restapi.",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/jobs": {
      "post": {
        "operationId": "createBatchJob",
        "summary": "Create a batch job",
        "description": "Submit a job. A closed job carries all its URLs up front in `tasks`; an open job is created empty and receives URLs through addBatchTasks until one call sets `last_batch`. `zenrows_params` applies to every task and a per-task `zenrows_params` overrides it. Returns 201 under 10,000 inline tasks and 202 at or above that (or for a CSV input); the body is identical, so treat both the same.",
        "tags": [
          "Batch"
        ],
        "servers": [
          {
            "url": "https://async.api.zenrows.com/v1",
            "description": "Batch (asynchronous jobs)"
          }
        ],
        "security": [
          {
            "apiKeyHeader": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "type",
                  "status"
                ],
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": [
                      "regular",
                      "scheduled"
                    ],
                    "description": "`regular` runs once; `scheduled` runs on a cron you set with putBatchSchedule."
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "closed",
                      "open"
                    ],
                    "description": "`closed` carries every URL now; `open` accepts URLs over time."
                  },
                  "name": {
                    "type": "string",
                    "description": "Your own label for the job."
                  },
                  "zenrows_params": {
                    "type": "object",
                    "description": "Fetch parameters applied to every task, using the names in the fetchPage operation.",
                    "additionalProperties": true
                  },
                  "tasks": {
                    "type": "array",
                    "description": "The URLs to run. Up to 10,000 per call.",
                    "items": {
                      "type": "object",
                      "required": [
                        "url"
                      ],
                      "properties": {
                        "url": {
                          "type": "string",
                          "format": "uri"
                        },
                        "external_id": {
                          "type": "string",
                          "description": "Your own identifier, returned with the result so you can join it back."
                        },
                        "zenrows_params": {
                          "type": "object",
                          "description": "Overrides the job-level parameters for this URL.",
                          "additionalProperties": true
                        }
                      }
                    }
                  },
                  "input_id": {
                    "type": "string",
                    "description": "Identifier returned by uploadBatchInput, to run a job from an uploaded CSV instead of inline tasks."
                  },
                  "webhook": {
                    "type": "object",
                    "description": "Where to deliver results as they complete.",
                    "additionalProperties": true
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Job accepted, under 10,000 inline tasks.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "202": {
            "description": "Job accepted, 10,000 tasks or more, or a CSV input. Task rows keep writing for a few seconds, so results pages can be partial at first.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "get": {
        "operationId": "listBatchJobs",
        "summary": "List batch jobs",
        "description": "Page through the jobs on the account, newest first.",
        "tags": [
          "Batch"
        ],
        "servers": [
          {
            "url": "https://async.api.zenrows.com/v1",
            "description": "Batch (asynchronous jobs)"
          }
        ],
        "security": [
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "status",
            "in": "query",
            "description": "Filter by whether the job still accepts tasks.",
            "schema": {
              "type": "string",
              "enum": [
                "open",
                "closed"
              ]
            }
          },
          {
            "name": "type",
            "in": "query",
            "description": "Filter by job type.",
            "schema": {
              "type": "string",
              "enum": [
                "regular",
                "scheduled"
              ]
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "`next_cursor` from the previous page.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of jobs and the cursor for the next one.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Documented at https://docs.zenrows.com/batch/developer-guide-restapi.",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/jobs/{job_id}": {
      "get": {
        "operationId": "getBatchJob",
        "summary": "Read a job",
        "description": "Return the job and its latest run, including `latest_run.status` and `latest_run.stats`. Poll this, or take a webhook, to know when a run is done.",
        "tags": [
          "Batch"
        ],
        "servers": [
          {
            "url": "https://async.api.zenrows.com/v1",
            "description": "Batch (asynchronous jobs)"
          }
        ],
        "security": [
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "description": "Identifier returned when the job was created.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The job and its latest run.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Job"
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/jobs/{job_id}/tasks": {
      "post": {
        "operationId": "addBatchTasks",
        "summary": "Add URLs to an open job",
        "description": "Append up to 10,000 URLs to an open job. Send `last_batch: true` on the final call to close it; later additions then return 409.",
        "tags": [
          "Batch"
        ],
        "servers": [
          {
            "url": "https://async.api.zenrows.com/v1",
            "description": "Batch (asynchronous jobs)"
          }
        ],
        "security": [
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "description": "Identifier returned when the job was created.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "tasks"
                ],
                "properties": {
                  "tasks": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "url"
                      ],
                      "properties": {
                        "url": {
                          "type": "string",
                          "format": "uri"
                        },
                        "external_id": {
                          "type": "string"
                        },
                        "zenrows_params": {
                          "type": "object",
                          "additionalProperties": true
                        }
                      }
                    }
                  },
                  "last_batch": {
                    "type": "boolean",
                    "description": "Closes the job after this batch."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The tasks accepted for the job.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Documented at https://docs.zenrows.com/batch/developer-guide-restapi.",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/jobs/{job_id}/close": {
      "post": {
        "operationId": "closeBatchJob",
        "summary": "Close an open job",
        "description": "Lock an open job so it accepts no further tasks. Equivalent to `last_batch` on the last add.",
        "tags": [
          "Batch"
        ],
        "servers": [
          {
            "url": "https://async.api.zenrows.com/v1",
            "description": "Batch (asynchronous jobs)"
          }
        ],
        "security": [
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "description": "Identifier returned when the job was created.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The job, now closed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Documented at https://docs.zenrows.com/batch/developer-guide-restapi.",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/jobs/{job_id}/stop": {
      "post": {
        "operationId": "stopBatchRun",
        "summary": "Stop the current run",
        "description": "Abandon the run in flight. Completed tasks keep their results.",
        "tags": [
          "Batch"
        ],
        "servers": [
          {
            "url": "https://async.api.zenrows.com/v1",
            "description": "Batch (asynchronous jobs)"
          }
        ],
        "security": [
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "description": "Identifier returned when the job was created.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The stopped run.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Documented at https://docs.zenrows.com/batch/developer-guide-restapi.",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/jobs/{job_id}/pause": {
      "post": {
        "operationId": "pauseBatchRun",
        "summary": "Pause the current run",
        "description": "Stop dispatching new tasks without abandoning the run.",
        "tags": [
          "Batch"
        ],
        "servers": [
          {
            "url": "https://async.api.zenrows.com/v1",
            "description": "Batch (asynchronous jobs)"
          }
        ],
        "security": [
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "description": "Identifier returned when the job was created.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The paused run.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Documented at https://docs.zenrows.com/batch/developer-guide-restapi.",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/jobs/{job_id}/resume": {
      "post": {
        "operationId": "resumeBatchRun",
        "summary": "Resume a paused run",
        "description": "Continue dispatching the remaining tasks of a paused run.",
        "tags": [
          "Batch"
        ],
        "servers": [
          {
            "url": "https://async.api.zenrows.com/v1",
            "description": "Batch (asynchronous jobs)"
          }
        ],
        "security": [
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "description": "Identifier returned when the job was created.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The resumed run.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Documented at https://docs.zenrows.com/batch/developer-guide-restapi.",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/jobs/{job_id}/cancel": {
      "post": {
        "operationId": "cancelBatchJob",
        "summary": "Cancel a job",
        "description": "Cancel the job and its pending work.",
        "tags": [
          "Batch"
        ],
        "servers": [
          {
            "url": "https://async.api.zenrows.com/v1",
            "description": "Batch (asynchronous jobs)"
          }
        ],
        "security": [
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "description": "Identifier returned when the job was created.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The cancelled job.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Documented at https://docs.zenrows.com/batch/developer-guide-restapi.",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/jobs/{job_id}/rerun": {
      "post": {
        "operationId": "rerunBatchJob",
        "summary": "Run a job again",
        "description": "Start a new run of the same job. Use it to refresh a dataset on demand, or to retry only what failed.",
        "tags": [
          "Batch"
        ],
        "servers": [
          {
            "url": "https://async.api.zenrows.com/v1",
            "description": "Batch (asynchronous jobs)"
          }
        ],
        "security": [
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "description": "Identifier returned when the job was created.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "only_failed": {
                    "type": "boolean",
                    "description": "Rerun only the tasks that failed in the previous run."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The new run.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Documented at https://docs.zenrows.com/batch/developer-guide-restapi.",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/jobs/{job_id}/results": {
      "get": {
        "operationId": "getBatchResults",
        "summary": "Read a job's results",
        "description": "Page through the per-URL results of a run: the status, the content or its location, and your `external_id` where you set one.",
        "tags": [
          "Batch"
        ],
        "servers": [
          {
            "url": "https://async.api.zenrows.com/v1",
            "description": "Batch (asynchronous jobs)"
          }
        ],
        "security": [
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "description": "Identifier returned when the job was created.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "status",
            "in": "query",
            "description": "Filter by task outcome.",
            "schema": {
              "type": "string",
              "enum": [
                "successful",
                "failed"
              ]
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "description": "`next_cursor` from the previous page.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "A page of task results and the cursor for the next one.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Documented at https://docs.zenrows.com/batch/developer-guide-restapi.",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/jobs/{job_id}/tasks/{task_id}/content": {
      "get": {
        "operationId": "getBatchTaskContent",
        "summary": "Download one task's content",
        "description": "Return the stored content for a single task of a job.",
        "tags": [
          "Batch"
        ],
        "servers": [
          {
            "url": "https://async.api.zenrows.com/v1",
            "description": "Batch (asynchronous jobs)"
          }
        ],
        "security": [
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "description": "Identifier returned when the job was created.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "description": "Identifier of one task (one URL) inside the job.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The task's content, in the format the job requested.",
            "content": {
              "*/*": {
                "schema": {
                  "type": "string",
                  "description": "Stored page content."
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/jobs/{job_id}/runs": {
      "get": {
        "operationId": "listBatchRuns",
        "summary": "List a job's runs",
        "description": "Every run of the job, newest first, with its stats.",
        "tags": [
          "Batch"
        ],
        "servers": [
          {
            "url": "https://async.api.zenrows.com/v1",
            "description": "Batch (asynchronous jobs)"
          }
        ],
        "security": [
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "description": "Identifier returned when the job was created.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The job's runs.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Documented at https://docs.zenrows.com/batch/developer-guide-restapi.",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/jobs/{job_id}/runs/{run_id}": {
      "delete": {
        "operationId": "deleteBatchRun",
        "summary": "Delete a run",
        "description": "Remove a run and the results it holds.",
        "tags": [
          "Batch"
        ],
        "servers": [
          {
            "url": "https://async.api.zenrows.com/v1",
            "description": "Batch (asynchronous jobs)"
          }
        ],
        "security": [
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "description": "Identifier returned when the job was created.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "description": "Identifier of one run of the job.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "The run was deleted."
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/jobs/{job_id}/runs/{run_id}/exports": {
      "post": {
        "operationId": "createBatchExport",
        "summary": "Export a run as a ZIP",
        "description": "Ask for a bulk export of a run's content. The export is prepared asynchronously and downloaded from the URL in the response.",
        "tags": [
          "Batch"
        ],
        "servers": [
          {
            "url": "https://async.api.zenrows.com/v1",
            "description": "Batch (asynchronous jobs)"
          }
        ],
        "security": [
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "description": "Identifier returned when the job was created.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "run_id",
            "in": "path",
            "required": true,
            "description": "Identifier of one run of the job.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The export and where to collect it.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Documented at https://docs.zenrows.com/batch/developer-guide-restapi.",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/jobs/{job_id}/schedule": {
      "put": {
        "operationId": "putBatchSchedule",
        "summary": "Set a job's schedule",
        "description": "Give a scheduled job its cron expression and timezone.",
        "tags": [
          "Batch"
        ],
        "servers": [
          {
            "url": "https://async.api.zenrows.com/v1",
            "description": "Batch (asynchronous jobs)"
          }
        ],
        "security": [
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "description": "Identifier returned when the job was created.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "cron": {
                    "type": "string",
                    "description": "Cron expression for the run."
                  },
                  "timezone": {
                    "type": "string",
                    "description": "IANA timezone the cron is read in."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The stored schedule.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Documented at https://docs.zenrows.com/batch/developer-guide-restapi.",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/jobs/{job_id}/schedule/state": {
      "post": {
        "operationId": "setBatchScheduleState",
        "summary": "Enable or disable a schedule",
        "description": "Turn a scheduled job on or off without deleting its schedule.",
        "tags": [
          "Batch"
        ],
        "servers": [
          {
            "url": "https://async.api.zenrows.com/v1",
            "description": "Batch (asynchronous jobs)"
          }
        ],
        "security": [
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "description": "Identifier returned when the job was created.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "enabled": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The schedule's new state.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Documented at https://docs.zenrows.com/batch/developer-guide-restapi.",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/jobs/{job_id}/webhook": {
      "put": {
        "operationId": "putBatchWebhook",
        "summary": "Set a job's webhook",
        "description": "Deliver results to your endpoint as tasks complete, instead of polling.",
        "tags": [
          "Batch"
        ],
        "servers": [
          {
            "url": "https://async.api.zenrows.com/v1",
            "description": "Batch (asynchronous jobs)"
          }
        ],
        "security": [
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "description": "Identifier returned when the job was created.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The stored webhook.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Documented at https://docs.zenrows.com/batch/developer-guide-restapi.",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteBatchWebhook",
        "summary": "Remove a job's webhook",
        "description": "Stop delivering this job's results to a webhook.",
        "tags": [
          "Batch"
        ],
        "servers": [
          {
            "url": "https://async.api.zenrows.com/v1",
            "description": "Batch (asynchronous jobs)"
          }
        ],
        "security": [
          {
            "apiKeyHeader": []
          }
        ],
        "parameters": [
          {
            "name": "job_id",
            "in": "path",
            "required": true,
            "description": "Identifier returned when the job was created.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "The webhook was removed."
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/job_inputs": {
      "post": {
        "operationId": "uploadBatchInput",
        "summary": "Upload a CSV of URLs",
        "description": "Upload a CSV to run as a job, for inputs too large to send inline. The identifier it returns goes into createBatchJob as `input_id`.",
        "tags": [
          "Batch"
        ],
        "servers": [
          {
            "url": "https://async.api.zenrows.com/v1",
            "description": "Batch (asynchronous jobs)"
          }
        ],
        "security": [
          {
            "apiKeyHeader": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "text/csv": {
              "schema": {
                "type": "string",
                "description": "CSV whose rows carry the URLs and any per-URL columns."
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The stored input and its identifier.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Documented at https://docs.zenrows.com/batch/developer-guide-restapi.",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/webhook/test": {
      "post": {
        "operationId": "testWebhook",
        "summary": "Send a test webhook",
        "description": "Deliver a sample payload to your endpoint so you can verify the receiver and the signature before a real run.",
        "tags": [
          "Batch"
        ],
        "servers": [
          {
            "url": "https://async.api.zenrows.com/v1",
            "description": "Batch (asynchronous jobs)"
          }
        ],
        "security": [
          {
            "apiKeyHeader": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The delivery attempt and its outcome.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Documented at https://docs.zenrows.com/batch/developer-guide-restapi.",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/hmac/keys": {
      "get": {
        "operationId": "listHmacKeys",
        "summary": "List webhook signing keys",
        "description": "The HMAC keys your webhooks are signed with, so you can verify deliveries.",
        "tags": [
          "Batch"
        ],
        "servers": [
          {
            "url": "https://async.api.zenrows.com/v1",
            "description": "Batch (asynchronous jobs)"
          }
        ],
        "security": [
          {
            "apiKeyHeader": []
          }
        ],
        "responses": {
          "200": {
            "description": "The account's signing keys.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Documented at https://docs.zenrows.com/batch/developer-guide-restapi.",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/hmac/keys/rotate": {
      "post": {
        "operationId": "startHmacKeyRotation",
        "summary": "Start a key rotation",
        "description": "Issue a new signing key alongside the current one so you can accept both while you deploy.",
        "tags": [
          "Batch"
        ],
        "servers": [
          {
            "url": "https://async.api.zenrows.com/v1",
            "description": "Batch (asynchronous jobs)"
          }
        ],
        "security": [
          {
            "apiKeyHeader": []
          }
        ],
        "responses": {
          "200": {
            "description": "The new key, pending finalisation.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Documented at https://docs.zenrows.com/batch/developer-guide-restapi.",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "cancelHmacKeyRotation",
        "summary": "Cancel a key rotation",
        "description": "Discard a pending key and keep signing with the current one.",
        "tags": [
          "Batch"
        ],
        "servers": [
          {
            "url": "https://async.api.zenrows.com/v1",
            "description": "Batch (asynchronous jobs)"
          }
        ],
        "security": [
          {
            "apiKeyHeader": []
          }
        ],
        "responses": {
          "204": {
            "description": "The pending rotation was cancelled."
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/hmac/keys/rotate/finalize": {
      "post": {
        "operationId": "finalizeHmacKeyRotation",
        "summary": "Finish a key rotation",
        "description": "Promote the pending key and retire the previous one.",
        "tags": [
          "Batch"
        ],
        "servers": [
          {
            "url": "https://async.api.zenrows.com/v1",
            "description": "Batch (asynchronous jobs)"
          }
        ],
        "security": [
          {
            "apiKeyHeader": []
          }
        ],
        "responses": {
          "200": {
            "description": "The active key after rotation.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Documented at https://docs.zenrows.com/batch/developer-guide-restapi.",
                  "additionalProperties": true
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed, or a parameter combination is not allowed.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "The API key is missing or invalid.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "402": {
            "description": "The account is out of credits, or the plan does not include this capability.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Zenrows reached the target but could not return it under the requested configuration.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Error `AUTH008`: every concurrency slot on the plan is occupied. There is no fixed requests-per-minute quota to wait out and no Retry-After to read: a slot frees when one of your requests in flight finishes. Read `Concurrency-Remaining` on any response to pace yourself, and back off exponentially before retrying. Documented at https://docs.zenrows.com/api-error-codes#AUTH008 and https://docs.zenrows.com/fetch/features/concurrency.",
            "headers": {
              "Concurrency-Limit": {
                "$ref": "#/components/headers/ConcurrencyLimit"
              },
              "Concurrency-Remaining": {
                "$ref": "#/components/headers/ConcurrencyRemaining"
              },
              "X-Request-Cost": {
                "$ref": "#/components/headers/XRequestCost"
              },
              "X-Request-Id": {
                "$ref": "#/components/headers/XRequestId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "headers": {
      "ConcurrencyLimit": {
        "description": "Concurrent requests this plan allows. The rate limit, in the unit Zenrows meters: slots in flight, not requests per interval.",
        "schema": {
          "type": "integer",
          "example": 20
        }
      },
      "ConcurrencyRemaining": {
        "description": "Free slots at the moment the request was received. Zero means the next request is refused with 429 until one finishes.",
        "schema": {
          "type": "integer",
          "example": 17
        }
      },
      "XRequestCost": {
        "description": "Credits this request cost, which varies with the features it enabled.",
        "schema": {
          "type": "number",
          "example": 0.001
        }
      },
      "XRequestId": {
        "description": "Identifier for this request. Quote it when reporting a problem.",
        "schema": {
          "type": "string",
          "example": "67fa4e35647515d8ad61bb3ee041e1bb"
        }
      },
      "RateLimitPolicy": {
        "description": "The standing rule, as a structured field: `\"signup\";q=3;w=86400` is three signups per client IP per 24 hours. Admin-editable, so read it rather than assuming three.",
        "schema": {
          "type": "string",
          "example": "\"signup\";q=3;w=86400"
        }
      },
      "RateLimit": {
        "description": "Where this caller stands: `r` is signups left, `t` is seconds until one frees. `t` counts from the oldest signup still inside the window, so it is a real wait, not the window length restated.",
        "schema": {
          "type": "string",
          "example": "\"signup\";r=1;t=52341"
        }
      },
      "RetryAfter": {
        "description": "Seconds to wait before signing up again. Present only when nothing is left.",
        "schema": {
          "type": "integer",
          "example": 52341
        }
      }
    },
    "securitySchemes": {
      "apiKeyQuery": {
        "type": "apiKey",
        "in": "query",
        "name": "apikey",
        "description": "Fetch and Extract read the key from the `apikey` query parameter. Keys are per account and self-serve: create one at https://app.zenrows.com, or, for an agent with no human present, `POST https://app.zenrows.com/api/agent/signup`."
      },
      "apiKeyHeader": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "Batch reads the same key from the `X-API-Key` header."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "description": "Zenrows error envelope. `code` is the stable identifier to branch on; the catalogue is published at https://docs.zenrows.com/api-error-codes.",
        "properties": {
          "code": {
            "type": "string",
            "example": "AUTH001"
          },
          "status": {
            "type": "integer",
            "example": 401
          },
          "title": {
            "type": "string"
          },
          "detail": {
            "type": "string"
          }
        }
      },
      "SignupError": {
        "type": "object",
        "description": "The onboarding surface has its own error shape, flatter than the API's envelope. Branch on `error`.",
        "properties": {
          "error": {
            "type": "string",
            "examples": [
              "rate_limited",
              "signup_disabled",
              "signup_failed",
              "invalid_key"
            ]
          },
          "message": {
            "type": "string"
          }
        }
      },
      "Job": {
        "type": "object",
        "description": "A batch job and the state of its most recent run.",
        "properties": {
          "job_id": {
            "type": "string",
            "description": "Identifier to poll and to collect results with."
          },
          "name": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "regular",
              "scheduled"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "open",
              "closed"
            ],
            "description": "Whether the job still accepts new tasks."
          },
          "latest_run": {
            "type": "object",
            "description": "The most recent run of this job.",
            "properties": {
              "run_id": {
                "type": "string"
              },
              "status": {
                "type": "string",
                "description": "Run state. `completed`, `stopped` and `deleted` are terminal.",
                "examples": [
                  "running",
                  "completed",
                  "stopped",
                  "deleted"
                ]
              },
              "stats": {
                "type": "object",
                "description": "Task counters for the run.",
                "properties": {
                  "total": {
                    "type": "integer"
                  },
                  "completed": {
                    "type": "integer"
                  },
                  "successful": {
                    "type": "integer"
                  },
                  "failed": {
                    "type": "integer"
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
