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

# OpenAI Agents SDK + Runloop

> Integrate Runloop cloud sandboxes with the OpenAI Agents SDK for secure, stateful AI agent execution.

A comprehensive guide to integrating Runloop cloud sandboxes with the OpenAI Agents SDK.

## Introduction

[Runloop](https://runloop.ai) is a cloud sandbox provider that offers secure, isolated execution environments for AI agents. Unlike local Docker containers, Runloop provides fully managed cloud sandboxes with powerful features including:

* **Cloud-native sandboxes**: No local Docker installation required
* **Pre-configured blueprints**: Choose from optimized environment templates
* **Suspend and resume**: Pause sandboxes to save state and costs, then resume exactly where you left off
* **Root access**: Full system control when needed for package installation and configuration
* **Docker-in-Docker support**: Run containers inside your sandbox for complex workloads

### When to Use Runloop

Choose Runloop over other sandbox providers when you need:

* Cloud-hosted execution without managing infrastructure
* The ability to suspend long-running tasks and resume later
* Docker-in-Docker capabilities for containerized workloads
* Pre-configured environments for common tech stacks
* Root access for system-level operations

For more details, visit the [official Runloop documentation](https://docs.runloop.ai).

## Prerequisites

Before getting started, ensure you have:

* **Python 3.10 or higher** installed
* **`uv` package manager** - [Install here](https://docs.astral.sh/uv/getting-started/installation/)
* **OpenAI API access** - For running the AI models
* **Runloop platform access** - For cloud sandbox provisioning

## Getting Your API Keys

You'll need API keys from both OpenAI and Runloop to use this integration.

### OpenAI API Key

1. Navigate to [https://platform.openai.com/api-keys](https://platform.openai.com/api-keys)
2. Sign in to your OpenAI account (or create one if you don't have one)
3. Click **"Create new secret key"**
4. Give your key a descriptive name like `"Agents SDK Development"`
5. Copy the key immediately (it won't be shown again)
6. Set it as an environment variable:

```bash theme={null}
export OPENAI_API_KEY=sk-...
```

### Runloop API Key

1. Navigate to [https://platform.runloop.ai/](https://platform.runloop.ai/)
2. Sign up for a Runloop account
   * **No credit card required**
   * **\$50 in free credits** to get started
3. Once logged in, navigate to your **API settings** or **API keys** section
4. Click **"Create API Key"** or similar option
5. Copy your API key
6. Set it as an environment variable:

```bash theme={null}
export RUNLOOP_API_KEY=...
```

You can add these to your `~/.bashrc`, `~/.zshrc`, or equivalent shell configuration file to make them persistent.

## Installation

The Runloop sandbox backend is available as an optional extra in the OpenAI Agents SDK.

### Install the SDK with Runloop Support

```bash theme={null}
uv sync --extra runloop
```

### Verify Installation

You can verify that Runloop support is installed correctly:

```bash theme={null}
uv run python -c "from agents.extensions.sandbox import RunloopSandboxClient; print('✓ Runloop support installed!')"
```

If you see the success message, you're ready to proceed!

## Basic Example: Your First Runloop Sandbox

This example demonstrates the core concepts of running a sandboxed agent with Runloop:

```python theme={null}
"""
basic_runloop_example.py - Simple Runloop sandbox demonstration
"""
import asyncio
import os

from agents import Runner
from agents.run import RunConfig
from agents.sandbox import Manifest, SandboxAgent, SandboxRunConfig
from agents.extensions.sandbox import RunloopSandboxClient, RunloopSandboxClientOptions


async def main():
    # Verify API keys are set
    if not os.environ.get("OPENAI_API_KEY"):
        raise SystemExit("OPENAI_API_KEY must be set")
    if not os.environ.get("RUNLOOP_API_KEY"):
        raise SystemExit("RUNLOOP_API_KEY must be set")

    # Create a simple workspace manifest
    manifest = Manifest(
        root="/home/user",  # Default workspace root for Runloop
        entries={
            "README.md": {
                "type": "text",
                "text": (
                    "# Demo Project\n\n"
                    "This workspace demonstrates Runloop sandbox integration.\n"
                ),
            },
            "data.txt": {
                "type": "text",
                "text": "Sample data: 42, 100, 256\n",
            },
        },
    )

    # Configure the sandbox agent
    agent = SandboxAgent(
        name="Runloop Assistant",
        model="gpt-4o",
        instructions=(
            "You are a helpful assistant with access to a cloud sandbox. "
            "Inspect the workspace files and answer questions about them."
        ),
        default_manifest=manifest,
    )

    # Create Runloop sandbox client
    client = RunloopSandboxClient()

    # Configure the run with Runloop backend
    run_config = RunConfig(
        sandbox=SandboxRunConfig(
            client=client,
            options=RunloopSandboxClientOptions(
                # Optional: specify a blueprint for pre-configured environments
                # blueprint_name="runloop/universal-ubuntu-24.04-x86_64-dnd",
                pause_on_exit=False,  # Set to True to suspend instead of delete
            ),
        ),
        workflow_name="Basic Runloop Example",
    )

    try:
        # Run the agent
        result = await Runner.run(
            agent,
            "What files are in the workspace? Summarize their contents.",
            run_config=run_config,
        )

        print("Agent response:")
        print(result.final_output)

    finally:
        # Clean up the client
        await client.close()


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

### How to Run

Save the code above as `basic_runloop_example.py` and run:

```bash theme={null}
uv run python basic_runloop_example.py
```

### What's Happening

1. **Manifest Creation**: We define a simple workspace with two text files
2. **SandboxAgent**: Configured with instructions and the default workspace
3. **RunloopSandboxClient**: Manages the connection to Runloop's API
4. **RunConfig**: Ties together the sandbox client, options, and workflow
5. **Execution**: The agent spins up a cloud sandbox, materializes the workspace, executes the task, and returns results

The sandbox is automatically created, the agent executes the task, and then the sandbox is cleaned up (unless `pause_on_exit=True`).

## Advanced Example: Docker-in-Docker with PostgreSQL Suspend/Resume

This advanced example showcases Runloop's unique suspend/resume capability. We'll:

1. Create a sandbox with Docker-in-Docker support
2. Install and configure PostgreSQL
3. Insert data into a database
4. Suspend the sandbox (preserving all state)
5. Serialize the session for later use
6. Resume the sandbox from the suspended state
7. Verify that installed packages, files, and database data persist

```python theme={null}
"""
dockerindocker_postgres_example.py - Advanced Runloop suspend/resume demonstration

This example demonstrates:
- Using custom blueprints (Docker-in-Docker)
- Root user access for package installation
- Database operations in a sandbox
- Suspending and resuming sandbox state
- State persistence across suspend/resume cycles
"""
import asyncio
import os
import json

from agents import Runner
from agents.run import RunConfig
from agents.sandbox import Manifest, SandboxAgent, SandboxRunConfig
from agents.extensions.sandbox import (
    RunloopSandboxClient,
    RunloopSandboxClientOptions,
    RunloopUserParameters,
)


async def main():
    # Verify API keys
    if not os.environ.get("OPENAI_API_KEY"):
        raise SystemExit("OPENAI_API_KEY must be set")
    if not os.environ.get("RUNLOOP_API_KEY"):
        raise SystemExit("RUNLOOP_API_KEY must be set")

    print("=== Phase 1: Creating sandbox and installing PostgreSQL ===\n")

    # Create a manifest with a workspace marker
    manifest = Manifest(
        root="/root",  # Root user uses /root as home
        entries={
            "workspace_marker.txt": {
                "type": "text",
                "text": "This file was created in the initial workspace setup.\n",
            },
        },
    )

    # Configure agent for database setup
    setup_agent = SandboxAgent(
        name="Database Setup Agent",
        model="gpt-4o",
        instructions=(
            "You are a database administrator with root access. "
            "Install PostgreSQL, create a database, create a table, and insert sample data. "
            "Verify the installation and data insertion by querying the database."
        ),
        default_manifest=manifest,
    )

    # Create Runloop client
    client = RunloopSandboxClient()

    # Configure sandbox with Docker-in-Docker blueprint and root access
    run_config = RunConfig(
        sandbox=SandboxRunConfig(
            client=client,
            options=RunloopSandboxClientOptions(
                # Use Docker-in-Docker capable blueprint
                blueprint_name="runloop/universal-ubuntu-24.04-x86_64-dnd",
                # Enable suspend on exit instead of deletion
                pause_on_exit=True,
                # Launch as root user for package installation
                user_parameters=RunloopUserParameters(username="root", uid=0),
                # Optional: give the sandbox a friendly name
                name="postgres-demo-sandbox",
            ),
        ),
        workflow_name="PostgreSQL Suspend/Resume Demo",
    )

    try:
        # Phase 1: Setup database
        print("Installing PostgreSQL and setting up database...")
        setup_result = await Runner.run(
            setup_agent,
            (
                "Install PostgreSQL using apt. Then as the postgres user, "
                "create a database called 'demo_db', create a table called 'users' "
                "with columns 'id' (serial) and 'name' (text), and insert three rows: "
                "Alice, Bob, and Charlie. Verify by running a SELECT query."
            ),
            run_config=run_config,
        )

        print("\nSetup Result:")
        print(setup_result.final_output)
        print("\n" + "="*60 + "\n")

        # Phase 2: Suspend and serialize
        print("=== Phase 2: Suspending sandbox ===\n")

        # The sandbox is automatically suspended because pause_on_exit=True
        # Get the session state for serialization
        session_state = await client.get_session_state()

        if session_state:
            # Serialize the session state
            state_json = session_state.model_dump_json()
            print(f"Session state serialized ({len(state_json)} bytes)")

            # Save to file (in real use, save to database or storage)
            with open("/tmp/runloop_session_state.json", "w") as f:
                f.write(state_json)
            print("State saved to /tmp/runloop_session_state.json")

        print("\nSandbox is now suspended (not deleted)")
        print("Installed packages, files, and database contents are preserved")
        print("\n" + "="*60 + "\n")

        # Close the client (sandbox remains suspended in the cloud)
        await client.close()

        # Phase 3: Resume from saved state
        print("=== Phase 3: Resuming from suspended state ===\n")

        # In a real application, this could happen hours or days later
        # Load the saved session state
        with open("/tmp/runloop_session_state.json", "r") as f:
            loaded_state_json = f.read()

        print("Loaded session state from file")

        # Deserialize the state
        from agents.extensions.sandbox import RunloopSandboxSessionState
        loaded_state = RunloopSandboxSessionState.model_validate_json(loaded_state_json)

        # Create a new client and resume the session
        resume_client = RunloopSandboxClient()

        # Configure agent for verification
        verify_agent = SandboxAgent(
            name="Database Verification Agent",
            model="gpt-4o",
            instructions=(
                "You are verifying database persistence after resume. "
                "Check if PostgreSQL is still installed, the workspace marker file exists, "
                "and the database table contains the original data."
            ),
            default_manifest=manifest,
        )

        # Resume with the loaded state
        resume_config = RunConfig(
            sandbox=SandboxRunConfig(
                client=resume_client,
                # Pass the loaded state to resume the sandbox
                state=loaded_state,
            ),
            workflow_name="PostgreSQL Resume Verification",
        )

        # Phase 4: Verify persistence
        print("Verifying that state persisted across suspend/resume...")
        verify_result = await Runner.run(
            verify_agent,
            (
                "Verify the following: 1) PostgreSQL is installed (check version), "
                "2) The workspace_marker.txt file exists in /root, "
                "3) Query the demo_db database and list all users from the users table. "
                "Report all findings."
            ),
            run_config=resume_config,
        )

        print("\nVerification Result:")
        print(verify_result.final_output)
        print("\n" + "="*60 + "\n")

        print("✓ Success! The sandbox resumed with all state intact:")
        print("  • Installed packages (PostgreSQL) persisted")
        print("  • Workspace files persisted")
        print("  • Database contents persisted")

    finally:
        # Clean up
        await resume_client.close()


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

### How to Run

Save the code as `dockerindocker_postgres_example.py` and run:

```bash theme={null}
uv run python dockerindocker_postgres_example.py
```

### Understanding the Flow

#### Phase 1: Initial Setup

* Creates a sandbox using the Docker-in-Docker blueprint
* Launches with root user access (`uid=0`)
* Agent installs PostgreSQL via `apt`
* Creates database, table, and inserts data
* Creates a workspace marker file

#### Phase 2: Suspend

* With `pause_on_exit=True`, the sandbox is suspended (not deleted)
* Session state is serialized to JSON
* All installed packages, files, and database state are preserved in the cloud
* The client closes, but the sandbox remains suspended

#### Phase 3: Resume

* Session state is loaded from the saved JSON
* A new `RunloopSandboxClient` is created
* The sandbox is resumed using the `state` parameter
* The suspended sandbox comes back online with all state intact

#### Phase 4: Verification

* Agent verifies PostgreSQL is still installed
* Workspace marker file still exists
* Database table still contains the original rows

### Key Takeaways

1. **State Persistence**: Everything in the sandbox persists during suspend/resume:
   * Installed system packages
   * Filesystem contents
   * Running databases and their data
   * Environment variables and configurations

2. **Cost Optimization**: Suspend sandboxes during idle periods to save costs, then resume exactly where you left off

3. **Serialization**: Session state can be stored in databases, files, or any persistent storage for long-term management

4. **Root Access**: The `RunloopUserParameters(username="root", uid=0)` pattern enables system-level operations

5. **Blueprints**: Different blueprints provide different capabilities (Docker-in-Docker, GPU access, etc.)

## Configuration Options

### RunloopSandboxClientOptions

Configure your Runloop sandbox with these options:

```python theme={null}
from agents.extensions.sandbox import RunloopSandboxClientOptions

options = RunloopSandboxClientOptions(
    blueprint_name="runloop/universal-ubuntu-24.04-x86_64-dnd",
    pause_on_exit=True,
    user_parameters=RunloopUserParameters(username="root", uid=0),
    name="my-sandbox",
    timeouts=RunloopTimeouts(create_s=600),
    env_vars={"DATABASE_URL": "postgresql://localhost/mydb"},
)
```

#### Parameters

* **`blueprint_name`** (str | None): Name of a pre-configured environment template
  * Example: `"runloop/universal-ubuntu-24.04-x86_64-dnd"`
  * Find available blueprints in the [Runloop dashboard](https://platform.runloop.ai/blueprints/public)

* **`blueprint_id`** (str | None): Direct blueprint ID reference (alternative to `blueprint_name`)

* **`pause_on_exit`** (bool): When `True`, suspends the sandbox instead of deleting it
  * Default: `False`
  * Use for long-running tasks or to preserve state

* **`user_parameters`** (RunloopUserParameters | None): Custom user configuration
  * Controls the sandbox user and workspace root

* **`name`** (str | None): Human-readable name for the sandbox
  * Appears in the Runloop dashboard
  * Helpful for managing multiple sandboxes

* **`timeouts`** (RunloopTimeouts | None): Custom timeout configuration
  * See [RunloopTimeouts](#runlooptimeouts) section below

* **`env_vars`** (dict\[str, str] | None): Environment variables to set in the sandbox

* **`exposed_ports`** (tuple\[int, ...]): Ports to expose for external access
  * Example: `(8080, 5432)`

### RunloopUserParameters

Controls the user account in the sandbox:

```python theme={null}
from agents.extensions.sandbox import RunloopUserParameters

# Standard user (default behavior)
user_params = RunloopUserParameters(username="user", uid=1000)

# Root user for package installation
root_params = RunloopUserParameters(username="root", uid=0)
```

#### Parameters

* **`username`** (str): Username for the sandbox user
  * Standard: `"user"` (workspace root: `/home/user`)
  * Root: `"root"` (workspace root: `/root`)

* **`uid`** (int): User ID
  * Standard user: typically `1000` or higher
  * Root: `0`
  * Must be `>= 0`

<Warning>
  When using root (`uid=0`), the default workspace root changes from `/home/user` to `/root`.
</Warning>

### RunloopTimeouts

Fine-tune timeout settings for different operations:

```python theme={null}
from agents.extensions.sandbox import RunloopTimeouts

timeouts = RunloopTimeouts(
    create_s=600,           # 10 minutes for sandbox creation
    exec_timeout_unbounded_s=7200,  # 2 hours for long-running commands
    suspend_s=180,          # 3 minutes for suspend
    resume_s=600,           # 10 minutes for resume
)
```

#### Parameters

All timeouts are in seconds and must be `>= 1`:

* **`exec_timeout_unbounded_s`**: Maximum execution time for unbounded commands
  * Default: `86400` (24 hours)

* **`create_s`**: Timeout for sandbox creation
  * Default: `300` (5 minutes)

* **`file_upload_s`**: Timeout for file uploads
  * Default: `1800` (30 minutes)

* **`file_download_s`**: Timeout for file downloads
  * Default: `1800` (30 minutes)

* **`snapshot_s`**: Timeout for snapshot creation
  * Default: `300` (5 minutes)

* **`suspend_s`**: Timeout for suspending a sandbox
  * Default: `120` (2 minutes)

* **`resume_s`**: Timeout for resuming a suspended sandbox
  * Default: `300` (5 minutes)

* **`keepalive_s`**: Keepalive interval
  * Default: `10` (10 seconds)

* **`cleanup_s`**: Cleanup timeout
  * Default: `30` (30 seconds)

* **`fast_op_s`**: Timeout for fast operations
  * Default: `30` (30 seconds)

### Blueprints

Blueprints are pre-configured environment templates that provide specific capabilities.

#### What are Blueprints?

Blueprints are VM images with pre-installed software, configurations, and capabilities:

* **Base OS** with common utilities
* **Runtime environments** (Node.js, Python, etc.)
* **Special capabilities** (Docker-in-Docker, GPU access)
* **Optimized configurations** for specific workloads

#### Common Blueprints

* **`runloop/universal-ubuntu-24.04-x86_64-dnd`**: Ubuntu 24.04 with Docker-in-Docker support
  * Use when you need to run containers inside the sandbox
  * Supports `docker`, `docker-compose`, and container orchestration

#### When to Use Custom Blueprints

Use custom blueprints when you need:

* **Docker-in-Docker**: Running containerized workloads
* **Specific OS versions**: Ubuntu, Debian, Alpine, etc.
* **Pre-installed tools**: Avoid installation time on every run
* **GPU access**: For ML/AI workloads
* **Specialized environments**: Data science, web development, etc.

#### Finding Available Blueprints

Visit the [Runloop platform dashboard](https://platform.runloop.ai/blueprints/public) to browse available blueprints, or check the [Runloop documentation](/docs/devboxes/blueprints/overview) for the latest list.

## Key Features

### Suspend and Resume

One of Runloop's most powerful features is the ability to suspend a sandbox and resume it later with all state intact.

#### How It Works

1. **Suspend**: Instead of deleting the sandbox, Runloop creates a snapshot
2. **State Preservation**: Everything is saved:
   * Installed packages and binaries
   * Filesystem contents
   * Running processes (when possible)
   * Database contents
   * Environment variables
3. **Serialize**: Session state can be saved to your storage
4. **Resume**: Later, resume the sandbox from the saved state

#### When to Use Suspend/Resume

* **Long-running tasks**: Pause overnight, resume the next day
* **Cost optimization**: Only pay for active compute time
* **Checkpointing**: Save progress at key milestones
* **Development workflows**: Preserve complex setups between work sessions

#### Code Pattern

```python theme={null}
from agents.extensions.sandbox import (
    RunloopSandboxClient,
    RunloopSandboxClientOptions,
    RunloopSandboxSessionState,
)

# Initial run with suspend enabled
client = RunloopSandboxClient()
options = RunloopSandboxClientOptions(pause_on_exit=True)

# ... run agent tasks ...

# Get and serialize state
session_state = await client.get_session_state()
state_json = session_state.model_dump_json()

# Save state_json to database/file/storage
save_to_storage(state_json)

await client.close()  # Sandbox is suspended, not deleted

# --- Later, in a new session ---

# Load and deserialize state
state_json = load_from_storage()
loaded_state = RunloopSandboxSessionState.model_validate_json(state_json)

# Resume with the loaded state
resume_client = RunloopSandboxClient()
resume_config = RunConfig(
    sandbox=SandboxRunConfig(
        client=resume_client,
        state=loaded_state,  # Resume from here
    )
)

# Sandbox resumes with all state intact
```

#### Limitations and Considerations

* **Suspend time**: Suspending can take 1-3 minutes depending on sandbox size
* **Resume time**: Resuming can take 2-5 minutes
* **State size**: Large filesystems take longer to suspend/resume
* **Running processes**: Some processes may not resume cleanly (restart them if needed)
* **Costs**: Suspended sandboxes may incur minimal storage costs (check Runloop pricing)

### Root User Access

By default, sandboxes run as a non-root user. Root access enables system-level operations.

#### Why You Might Need Root

* **Package installation**: `apt install`, `yum install`, etc.
* **System configuration**: Editing `/etc` files, network setup
* **Service management**: `systemctl`, starting daemons
* **Docker operations**: Running Docker commands (Docker-in-Docker)

#### How to Enable Root Access

```python theme={null}
from agents.extensions.sandbox import RunloopUserParameters

user_parameters = RunloopUserParameters(username="root", uid=0)

options = RunloopSandboxClientOptions(
    user_parameters=user_parameters,
    # ...
)
```

#### Important Changes with Root Access

When running as root (`uid=0`):

* **Workspace root changes**: `/home/user` → `/root`
* **Update your manifest**: `Manifest(root="/root", ...)`
* **HOME environment variable**: Set to `/root`

#### Security Considerations

* **Use responsibly**: Root access is powerful—use only when necessary
* **Sandboxes are isolated**: Each sandbox is a separate VM, but still be cautious
* **Avoid in production**: For production agents, prefer principle of least privilege
* **Audit commands**: Review what commands the agent executes as root

### Workspace Management

The workspace is the directory where your files and code live in the sandbox.

#### Default Workspace Roots

* **Standard user**: `/home/user`
* **Root user**: `/root`

The workspace root is automatically set based on the user, but you can override it in your manifest.

#### Creating Manifests

Use the `Manifest` class to define workspace contents:

```python theme={null}
from agents.sandbox import Manifest

manifest = Manifest(
    root="/home/user",  # or "/root" for root user
    entries={
        "config.json": {
            "type": "text",
            "text": '{"setting": "value"}\n',
        },
        "scripts/setup.sh": {
            "type": "text",
            "text": "#!/bin/bash\necho 'Setting up...'\n",
        },
        "data/": {
            "type": "directory",
        },
    },
)
```

#### Reading Files from the Sandbox

During execution, use the shell tool to read files:

```python theme={null}
# Agent instruction:
"Read the contents of /home/user/config.json and summarize it."
```

Or use the sandbox session API:

```python theme={null}
content = await session.read_file("/home/user/output.txt")
```

#### Writing Files to the Sandbox

Agents can write files using shell commands:

```python theme={null}
# Agent instruction:
"Create a file at /home/user/results.txt with the analysis results."
```

Or programmatically:

```python theme={null}
await session.write_file(
    "/home/user/output.txt",
    "Analysis complete\n",
)
```

#### Archive Operations

Download the entire workspace as a tarball:

```python theme={null}
archive_bytes = await session.read_workspace_archive()

# Save locally
with open("workspace.tar", "wb") as f:
    f.write(archive_bytes)
```

Upload a workspace archive:

```python theme={null}
with open("workspace.tar", "rb") as f:
    archive_bytes = f.read()

await session.write_workspace_archive(archive_bytes)
```

## Troubleshooting

### Common Issues and Solutions

#### "Runloop sandbox examples require the optional repo extra"

**Problem**: You see this error when trying to import Runloop classes.

**Solution**: Install the Runloop extra:

```bash theme={null}
uv sync --extra runloop
```

Verify with:

```bash theme={null}
uv run python -c "from agents.extensions.sandbox import RunloopSandboxClient; print('OK')"
```

***

#### Authentication Errors

**Problem**: `APIStatusError: 401 Unauthorized` or similar authentication failures.

**Cause**: Missing or incorrect `RUNLOOP_API_KEY`.

**Solution**:

1. Verify the environment variable is set:
   ```bash theme={null}
   echo $RUNLOOP_API_KEY
   ```

2. Check for trailing spaces or quotes:
   ```bash theme={null}
   export RUNLOOP_API_KEY=your_key_here  # No quotes
   ```

3. Regenerate the key in the Runloop dashboard if needed

4. Ensure the key is active and not expired

***

#### Timeout Errors

**Problem**: `PollingTimeout` or operation timeout errors.

**Cause**: Operation took longer than the configured timeout.

**Solutions**:

1. Increase the relevant timeout:
   ```python theme={null}
   from agents.extensions.sandbox import RunloopTimeouts

   timeouts = RunloopTimeouts(
       create_s=600,  # 10 minutes instead of 5
       exec_timeout_unbounded_s=3600,  # 1 hour instead of 24
   )

   options = RunloopSandboxClientOptions(timeouts=timeouts)
   ```

2. Check the Runloop platform status

3. Verify your network connection is stable

4. Break large operations into smaller chunks

***

#### Blueprint Not Found

**Problem**: `NotFoundError` or "blueprint not found" when creating a sandbox.

**Cause**: Invalid `blueprint_name` or `blueprint_id`.

**Solutions**:

1. Verify the blueprint name spelling:
   ```python theme={null}
   # Correct
   blueprint_name="runloop/universal-ubuntu-24.04-x86_64-dnd"

   # Incorrect (missing hyphen)
   blueprint_name="runloop/universal-ubuntu-24.04-x86_64dnd"
   ```

2. Check available blueprints in your [Runloop dashboard](https://platform.runloop.ai/blueprints/public)

3. Remove the `blueprint_name` parameter to use the default blueprint

4. Contact Runloop support if a specific blueprint should be available

***

#### Session Resume Failures

**Problem**: Cannot resume a suspended sandbox.

**Possible causes and solutions**:

1. **`pause_on_exit` was not set**:
   * Ensure `pause_on_exit=True` in the original `RunloopSandboxClientOptions`
   * Without this, the sandbox is deleted instead of suspended

2. **Serialized state is corrupted**:
   * Verify the JSON is valid: `json.loads(state_json)`
   * Re-serialize from the original state if possible

3. **Sandbox was manually deleted**:
   * Check the Runloop dashboard to see if the sandbox still exists
   * If deleted, you'll need to create a new sandbox

***

#### Rate Limiting

**Problem**: `APIStatusError: 429 Too Many Requests`

**Cause**: Exceeded Runloop API rate limits.

**Solutions**:

1. Add exponential backoff retry logic
2. Space out sandbox creation requests
3. Reuse existing sandboxes when possible
4. Contact Runloop to discuss rate limit increases

***

#### Out of Credits

**Problem**: Sandbox creation fails with billing or quota errors.

**Cause**: Runloop account is out of credits or missing billing information.

**Solutions**:

1. Check your credit balance in the [Runloop dashboard](https://platform.runloop.ai/billing/usage)
2. Add more credits to your account
3. Clean up unused suspended sandboxes to free resources

## Additional Resources

### Official Documentation

* **OpenAI Agents SDK**: [https://github.com/openai/openai-agents-python](https://github.com/openai/openai-agents-python)
* **Runloop Platform**: [https://platform.runloop.ai/](https://platform.runloop.ai/)
* **Runloop Docs**: [https://docs.runloop.ai](https://docs.runloop.ai)

### Example Code

* **OpenAI Agents Examples**: [https://github.com/openai/openai-agents-python/tree/main/examples](https://github.com/openai/openai-agents-python/tree/main/examples)
* **Runloop Runner**: See `examples/sandbox/extensions/runloop_runner.py` in the SDK repository

### Getting Help

* **OpenAI Developer Forum**: [https://community.openai.com/](https://community.openai.com/)
* **Runloop Support**: Contact via the Runloop platform dashboard
* **GitHub Issues**: Report SDK issues at [https://github.com/openai/openai-agents-python/issues](https://github.com/openai/openai-agents-python/issues)

### Related Topics

* [OpenAI Agents SDK Quickstart](https://github.com/openai/openai-agents-python/blob/main/docs/quickstart.md)
* [Sandbox Agents Guide](https://github.com/openai/openai-agents-python/blob/main/docs/sandbox.md)
* [Session Management](https://github.com/openai/openai-agents-python/blob/main/docs/sessions/index.md)
* [Devbox Overview](/docs/devboxes/overview)
* [Blueprints](/docs/devboxes/blueprints/overview)
* [Runloop CLI](/docs/tools/rl-cli)
