> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.airtop.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.airtop.ai/_mcp/server.

Execute batch operations in parallel while automatically managing browser sessions and windows.

### Parameters

**`urls`** `BatchOperationUrl[]` — required

An array of URLs to process in parallel.

#### + Show 2 properties

**`url`** `string` — required

The URL to process.

---

**`context`** `Record<string, unknown>`

Additional context data to be passed with the URL.

---

---

**`operation`** `(input: BatchOperationInput) => Promise<BatchOperationResponse<T>>` — required

The operation function to execute for each URL.

#### + Show 2 objects

**`input`** `BatchOperationInput` — required

The input provided to the operation function.

#### + Show 4 properties

**`sessionId`** `string` — required

The ID of the browser session.

---

**`windowId`** `string` — required

The ID of the browser window.

---

**`liveViewUrl`** `string` — required

The URL that can be used to view the browser window in real-time.

---

**`operationUrl`** `BatchOperationUrl` — required

The URL being processed, including any context data.

---

---

**`response`** `BatchOperationResponse<T>` — required

The response returned by the operation function.

#### + Show 3 properties

**`data`** `T` — required

Contains the relevant data returned by the operation, which will ultimately be returned in the results array.

---

**`shouldHaltBatch`** `boolean`

If set to true, the batch operator will stop processing remaining URLs.

---

**`additionalUrls`** `BatchOperationUrl[]`

If set, additional URLs will be processed as part of the same batch operation.

---

---

---

**`config`** `BatchOperateConfig`

Configuration options for the batch operation.

#### + Show 4 properties

**`maxConcurrentSessions`** `number`

Maximum number of concurrent browser sessions. Defaults to 30.

---

**`maxWindowsPerSession`** `number`

Maximum number of windows per session. Defaults to 1 (recommended).

---

**`sessionConfig`** `AirtopSessionConfigV1`

Configuration for browser sessions.

---

**`onError`** `(error: BatchOperationError) => Promise<void>`

Callback function for handling errors.

#### + Show 5 properties

**`error.error`** `Error | string` — required

The error that occurred.

---

**`error.operationUrls`** `BatchOperationUrl[]` — required

The URLs that were being processed when the error occurred.

---

**`error.sessionId`** `string`

The ID of the session where the error occurred (if available).

---

**`error.windowId`** `string`

The ID of the window where the error occurred (if available).

---

**`error.liveViewUrl`** `string`

The live view URL of the window where the error occurred (if available).

---

---

---

### Returns

**`results`** `T[]` — required

An array containing the results from each operation, in the order that the operations were executed. Note that the
order of the input URLs does not necessarily match the order of the results.

---

**`Typescript`**

```typescript title="Typescript"
import { Airtop, BatchOperationUrl, BatchOperationInput, BatchOperationResponse } from '@airtop/sdk';

const client = new Airtop({ apiKey: 'your-api-key' });

// Define URLs to process
const urls: BatchOperationUrl[] = [
  {
    url: 'https://example.com/page1',
    context: { category: 'news' },
  },
  {
    url: 'https://example.com/page2',
    context: { category: 'blog' },
  },
];

// Define operation function
const operation = async (input: BatchOperationInput): Promise<BatchOperationResponse<string>> => {
  const { windowId, sessionId, liveViewUrl, operationUrl } = input;

  // Example: Run a custom query on each page
  const result = await client.windows.pageQuery({
    sessionId,
    windowId,
    prompt: `What is the main idea of this ${operationUrl.context?.category} page?`,
  });

  return {
    data: result.data.modelResponse,
    shouldHaltBatch: false,
    additionalUrls: [],
  };
};

// Execute batch operation
const results = await client.batchOperate({
  urls,
  operation,
  config: {
    maxConcurrentSessions: 30,
    maxWindowsPerSession: 1,
    onError: async (error) => {
      console.error(`Error processing URLs:`, error.operationUrls);
      console.error(`Error details:`, error.error);
    },
  },
});
```

**`Python`**

```python title="Python"
from airtop import AsyncAirtop, BatchOperationUrl, BatchOperationInput, BatchOperationResponse
from typing import Dict, Any

async def main():
    client = AsyncAirtop(api_key="your-api-key")

    # Define URLs to process
    urls = [
        BatchOperationUrl(
            url="https://example.com/page1",
            context={"category": "news"}
        ),
        BatchOperationUrl(
            url="https://example.com/page2",
            context={"category": "blog"}
        )
    ]

    # Define operation function
    async def operation(input: BatchOperationInput) -> BatchOperationResponse[str]:
        category = input.operation_url.context.get("category")

        # Example: Run a custom query on each page
        result = await client.windows.page_query(
            session_id=input.session_id,
            window_id=input.window_id,
            prompt=f"What is the main idea of this {category} page?"
        )

        return BatchOperationResponse(
            data=result.data.model_response,
            should_halt_batch=False,
            additional_urls=[]
        )

    async def handle_error(error: Dict[str, Any]) -> None:
        print(f"Error processing URLs: {error['operation_urls']}")
        print(f"Error details: {error['error']}")

    # Execute batch operation
    results = await client.batch_operate(
        urls=urls,
        operation=operation,
        config={
            "max_concurrent_sessions": 30,
            "max_windows_per_session": 1,
            "on_error": handle_error
        }
    )
```