> ## Documentation Index
> Fetch the complete documentation index at: https://docs.narada.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Structured Output

> Structure automation responses with Pydantic models for reliable data extraction

## Overview

The Narada Python SDK uses Pydantic models to define structured output schemas, ensuring consistent and type-safe data extraction from automation tasks.

<Frame>
  <iframe
    width="100%"
    height="400px"
    src="https://www.youtube.com/embed/VBXMOjWF5BQ"
    title="Narada SDK Demo with Structured Output"
    frameBorder="0"
    allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture"
    allowFullScreen
    style={{
  width: "100%",
  minHeight: "400px",
  borderRadius: "0.5rem",
}}
  />
</Frame>

## Using Structured Output

Define your data structure using Pydantic models and pass it to the SDK:

```python highlight={7-12, 21} theme={null}
import asyncio

from narada import Agent, BrowserEnvironment
from pydantic import BaseModel, Field

# Define your data structure
class JobListing(BaseModel):
    title: str = Field(description="Job title")
    company: str = Field(description="Company name")
    location: str = Field(description="Job location")
    salary: str | None = Field(description="Salary range if available")
    remote: bool = Field(description="Whether the job is remote")

async def main() -> None:
    env = BrowserEnvironment()
    agent = Agent(environment=env)

    try:
        # Use structured output to extract job data
        response = await agent.run(
            prompt='search for "Python developer" jobs on LinkedIn and extract details of the first job listing',
            output_schema=JobListing
        )

        # Access structured data
        job = response.structured_output
        assert job is not None
        print(f"Found job: {job.title} at {job.company}")
        print(f"Location: {job.location}")
        if job.salary:
            print(f"Salary: {job.salary}")
        print(f"Remote: {'Yes' if job.remote else 'No'}")
    finally:
        await env.close()

if __name__ == "__main__":
    asyncio.run(main())
```

## Supported Data Types

<Tabs>
  <Tab title="Basic Types">
    ```python theme={null}
    from pydantic import BaseModel, Field

    class UserProfile(BaseModel):
        name: str = Field(description="User's full name")
        age: int = Field(description="User's age")
        email: str = Field(description="User's email address")
        active: bool = Field(description="Whether user is active")
    ```
  </Tab>

  <Tab title="Optional Fields">
    ```python theme={null}
    from typing import Optional

    class Product(BaseModel):
        name: str = Field(description="Product name")
        price: float = Field(description="Product price")
        description: str | None = Field(description="Product description")
        stock: int | None = Field(description="Units in stock")
    ```
  </Tab>

  <Tab title="Lists">
    ```python theme={null}
    from typing import List

    class SearchResults(BaseModel):
        top_links: list[str] = Field(description="List of top result URLs")
    ```
  </Tab>

  <Tab title="Nested Models">
    ```python theme={null}
    class Address(BaseModel):
        street: str = Field(description="Street address")
        city: str = Field(description="City name")
        country: str = Field(description="Country name")

    class Company(BaseModel):
        name: str = Field(description="Company name")
        address: Address = Field(description="Company address")
        employee_count: int = Field(description="Number of employees")
    ```
  </Tab>
</Tabs>

## Best Practices

<CardGroup cols={2}>
  <Card title="Clear Descriptions" icon="comment">
    Add descriptive Field annotations to guide data extraction
  </Card>

  <Card title="Type Safety" icon="shield-check">
    Use appropriate types and Optional fields for reliable data
  </Card>

  <Card title="Modular Models" icon="cubes">
    Break complex schemas into smaller, reusable models
  </Card>

  <Card title="Validation" icon="check-double">
    Let Pydantic handle data validation automatically
  </Card>
</CardGroup>

<Tip>
  Use structured output whenever you need to extract specific data points from web pages. The SDK will ensure the data matches your schema exactly.
</Tip>
