> ## Documentation Index
> Fetch the complete documentation index at: https://browseruse-0aece648-magnus-concurrency-docs.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Structured output

> Get validated, typed data back from agent tasks.

Pass a Pydantic model (Python) or Zod schema (TypeScript) — `result.output` is automatically validated and converted to the typed object.

<Note>
  TypeScript requires **Zod v4** (`npm install zod@4`). Zod v3 is not compatible.
</Note>

<CodeGroup>
  ```python Python theme={null}
  from browser_use_sdk.v3 import AsyncBrowserUse
  from pydantic import BaseModel

  class Post(BaseModel):
      name: str
      points: int
      comments: int

  class HNPosts(BaseModel):
      posts: list[Post]

  client = AsyncBrowserUse()
  result = await client.run(
      "List the top 20 posts on Hacker News today with their points",
      output_schema=HNPosts,
  )
  for post in result.output.posts:
      print(f"{post.name} ({post.points} pts, {post.comments} comments)")
  ```

  ```typescript TypeScript theme={null}
  import { BrowserUse } from "browser-use-sdk/v3";
  import { z } from "zod";

  const Post = z.object({
    name: z.string(),
    points: z.number(),
    comments: z.number(),
  });

  const HNPosts = z.object({
    posts: z.array(Post),
  });

  const client = new BrowserUse();
  const result = await client.run(
    "List the top 20 posts on Hacker News today with their points",
    { schema: HNPosts },
  );
  for (const post of result.output.posts) {
    console.log(`${post.name} (${post.points} pts, ${post.comments} comments)`);
  }
  ```
</CodeGroup>

## Scrape multiple sites concurrently

Each `client.run()` call creates its own session, so you can run them in parallel with `asyncio.gather` (Python) or `Promise.all` (TypeScript). Every result is fully typed.

<CodeGroup>
  ```python Python theme={null}
  import asyncio
  from browser_use_sdk.v3 import AsyncBrowserUse
  from pydantic import BaseModel

  class Product(BaseModel):
      name: str
      price: str
      url: str

  class Results(BaseModel):
      products: list[Product]

  async def main():
      client = AsyncBrowserUse()

      sites = [
          "Find the top 3 laptops on amazon.com with their prices",
          "Find the top 3 laptops on bestbuy.com with their prices",
          "Find the top 3 laptops on newegg.com with their prices",
      ]

      results = await asyncio.gather(*[
          client.run(task, output_schema=Results)
          for task in sites
      ])

      for result in results:
          for p in result.output.products:
              print(f"{p.name} — {p.price}")

  asyncio.run(main())
  ```

  ```typescript TypeScript theme={null}
  import { BrowserUse } from "browser-use-sdk/v3";
  import { z } from "zod";

  const Product = z.object({
    name: z.string(),
    price: z.string(),
    url: z.string(),
  });

  const Results = z.object({
    products: z.array(Product),
  });

  const client = new BrowserUse();

  const sites = [
    "Find the top 3 laptops on amazon.com with their prices",
    "Find the top 3 laptops on bestbuy.com with their prices",
    "Find the top 3 laptops on newegg.com with their prices",
  ];

  const results = await Promise.all(
    sites.map((task) => client.run(task, { schema: Results }))
  );

  for (const result of results) {
    for (const p of result.output.products) {
      console.log(`${p.name} — ${p.price}`);
    }
  }
  ```
</CodeGroup>
