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

# Metadata

> Tag and query sessions with custom data

As your number of sessions grows, session metadata helps you organize and access them with customizable labels.

Session metadata can be attached to a session and later queried via the [List Sessions API](/reference/api/list-sessions).

### Why use metadata?

Consider running automated tests across multiple browser sessions. Without metadata, you'd struggle to track which session belongs to which test run. With metadata, you can attach a "run ID" to each session and easily query them later. Similarly, you might want to track the status of downloads or associate sessions with specific projects or teams. All of these are possible with metadata.

### Structure

Session metadata is a simple but flexible structure:

* All metadata is a customizable JSON object
* Your JSON object must be under 512 characters
* Data is organized in a nested structure using fields (no arrays supported yet)
* Only string values are supported for querying (convert numbers and booleans to strings)
* Metadata persists throughout the entire session lifecycle

Here's what a typical metadata structure looks like:

```json theme={null}
{
  "env": "staging"
}
```

A more extensive, nested object might look like:

```json theme={null}
{
  "run": {
    "id": "run-abc-123"
  },
  "env": "staging",
  "team": "platform"
}
```

## Attach metadata to a session

Pass the `userMetadata` parameter when creating a session via the [Create Session](/reference/api/create-a-session) endpoint. This metadata can be any JSON-serializable object.

Below is an example that attaches `{"env": "staging"}` to a session.

<Tabs>
  <Tab title="Node.js">
    <CodeGroup>
      ```javascript SDK theme={null}
      import Browserbase from "@browserbasehq/sdk";

      const bb = new Browserbase({ apiKey: process.env["BROWSERBASE_API_KEY"]! });

      const session = await bb.sessions.create({
        userMetadata: {
          env: "staging",
        },
      });
      console.log("Session URL: https://browserbase.com/sessions/" + session.id);
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Python">
    <CodeGroup>
      ```python SDK theme={null}
      from browserbase import Browserbase
      import os

      bb = Browserbase(api_key=os.environ["BROWSERBASE_API_KEY"])

      session = bb.sessions.create(
          user_metadata={
            "env": "staging",
          },
      )
      print(f"Session URL: https://browserbase.com/sessions/{session.id}")
      ```
    </CodeGroup>
  </Tab>
</Tabs>

## Query sessions by metadata

Pass a query string to the `q` parameter in [List Sessions](/reference/api/list-sessions) to filter sessions by metadata. The query string format is always `user_metadata['path']['to']['field']:'value'`.

Below is an example that finds all sessions with `{"env": "staging"}`.

<Tabs>
  <Tab title="Node.js">
    <CodeGroup>
      ```javascript SDK theme={null}
      import Browserbase from "@browserbasehq/sdk";

      const bb = new Browserbase({ apiKey: process.env["BROWSERBASE_API_KEY"]! });

      const query = "user_metadata['env']:'staging'";
      const sessions = await bb.sessions.list({ q: query });
      console.log(sessions);
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Python">
    <CodeGroup>
      ```python SDK theme={null}
      from browserbase import Browserbase
      import os

      bb = Browserbase(api_key=os.environ["BROWSERBASE_API_KEY"])

      query = "user_metadata['env']:'staging'"
      sessions = bb.sessions.list(q=query)
      print(sessions)
      ```
    </CodeGroup>
  </Tab>

  <Tab title="cURL">
    <CodeGroup>
      ```bash cURL theme={null}
      curl "https://api.browserbase.com/v1/sessions?q=user_metadata%5B%27env%27%5D%3A%27staging%27" \
        -H "X-BB-API-Key: $BROWSERBASE_API_KEY"
      ```
    </CodeGroup>

    <Note>
      URL encode the query string when calling the API directly to ensure it's properly parsed. The SDKs handle this automatically. In JavaScript, you can use encodeURIComponent("your-query-string-here") to do this.
    </Note>
  </Tab>
</Tabs>

If no sessions match, the API returns an empty list `[]`.

## Best practices

Use descriptive, consistent naming and keep your metadata structure shallow and intuitive.

**Tip:** Need to query numbers or booleans? Convert them to strings:

```json theme={null}
{
  "priority": "5",
  "active": "true"
}
```

## Limitations

* JSON object must be under 512 characters (think `JSON.stringify` and measuring the resulting length)
* Only field queries are supported (no array querying)
* Only string equality checks are available
* Only the `user_metadata` base is supported
