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

# Metadata

> Add custom context to your AI requests for better observability and analytics

<Info>
  This feature is available on all Portkey plans.
</Info>

## What is Metadata?

Metadata in Portkey allows you to attach custom contextual information to your AI requests. Think of it as tagging your requests with important business context that helps you:

* **Track usage** across different users, environments, or features
* **Filter logs** to isolate specific request types
* **Analyze patterns** in how your AI is being used
* **Audit activities** for compliance and security

```python theme={"system"}
# Example metadata
{
    "_user": "user-123",      # Who made this request?
    "environment": "prod",    # Where was it made from?
    "feature": "chat-assist", # What feature was using AI?
    "request_id": "42aff12"   # Your internal tracking ID
}
```

## Quick Implementation

<Tabs>
  <Tab title="Python">
    ```python theme={"system"}
    from portkey_ai import Portkey

    portkey = Portkey(
        api_key="PORTKEY_API_KEY",
        provider="@OPENAI_PROVIDER"
    )

    # Add metadata to track context
    response = portkey.with_options(
        metadata={
            "_user": "user-123",
            "environment": "production",
            "feature": "summarization",
            "request_id": "1729"
        }
    ).chat.completions.create(
        messages=[{"role": "user", "content": "Summarize this article"}],
        model="gpt-4"
    )
    ```
  </Tab>

  <Tab title="NodeJS">
    ```javascript theme={"system"}
    import {Portkey} from 'portkey-ai'

    const portkey = new Portkey({
        apiKey: "PORTKEY_API_KEY",
        provider:"@OPENAI_PROVIDER"
    })

    // Request with business context metadata
    const completion = await portkey.chat.completions.create(
        {
            messages: [{ role: 'user', content: 'Summarize this article' }],
            model: 'gpt-4',
        }, 
        {
            metadata: {
                "_user": "user-123",
                "environment": "production",
                "feature": "summarization",
                "request_id": "1729"
            }
        }
    );
    ```
  </Tab>

  <Tab title="OpenAI SDK">
    ```javascript theme={"system"}
    // Using with OpenAI SDK
    import OpenAI from 'openai';
    import { PORTKEY_GATEWAY_URL, createHeaders } from 'portkey-ai'

    const openai = new OpenAI({
      baseURL: PORTKEY_GATEWAY_URL,
      defaultHeaders: createHeaders({
        apiKey: "PORTKEY_API_KEY",
        metadata: {
          "_user": "user-123",
          "feature": "customer-support"
        }
      })
    });

    const completion = await openai.chat.completions.create({
      messages: [{ role: 'user', content: 'Help with my order' }],
      model: 'gpt-4',
    });
    ```
  </Tab>

  <Tab title="cURL">
    ```bash theme={"system"}
    curl https://api.portkey.ai/v1/chat/completions \
      -H "Content-Type: application/json" \
      -H "x-portkey-api-key: $PORTKEY_API_KEY" \
      -H "x-portkey-provider: $OPENAI_PROVIDER" \
      -H "x-portkey-metadata: {\"_user\":\"user-123\",\"feature\":\"search\"}" \
      -d '{
        "model": "gpt-4",
        "messages": [{"role": "user","content": "Find relevant docs"}]
      }'
    ```
  </Tab>
</Tabs>

## Common Use Cases

<CardGroup cols={2}>
  <Card title="User Analytics" icon="user">
    Track which users are using AI features by adding the `_user` identifier in metadata
  </Card>

  <Card title="Cost Attribution" icon="money-bill">
    Attribute AI costs to teams, features or products by adding identifiers in metadata
  </Card>

  <Card title="Environment Tracking" icon="server">
    Differentiate between dev/staging/prod usage with the `environment` metadata key
  </Card>

  <Card title="Feature Usage" icon="puzzle-piece">
    See which product features are using AI most heavily with feature identifiers
  </Card>
</CardGroup>

## Metadata Keys and Values

* You can send **any number** of metadata keys with each request
* All values must be **strings** with a maximum length of **128** characters
* Keys can be any string, but some have special meaning (like `_user`)

### Special Metadata Keys

| Key     | Purpose       | Notes                                                |
| ------- | ------------- | ---------------------------------------------------- |
| `_user` | User tracking | Powers user-level analytics in the Portkey dashboard |

<Info>
  **About the `_user` key:** If you pass a `user` field in your OpenAI request body, we'll automatically copy it to the `_user` metadata key. If both exist, the explicit `_user` metadata value takes precedence.
</Info>

## Where to See Your Metadata

### Analytics Dashboard

The Analytics dashboard's [Summary tab](/product/observability/analytics#summary) lets you group requests by any metadata key to view aggregate stats:

<Frame>
  <img src="https://mintcdn.com/portkey-docs/EKxolPDRqqOR-ZgU/images/metadata.png?fit=max&auto=format&n=EKxolPDRqqOR-ZgU&q=85&s=43e9a3ef202a9d61460a098c4bb78218" alt="Summary tab grouped by a metadata key" width="1079" height="719" data-path="images/metadata.png" />
</Frame>

### Request Logs

You can also apply any metadata filters to the logs or analytics and filter data by any metadata key you've used:

<Frame>
  <img src="https://mintcdn.com/portkey-docs/EKxolPDRqqOR-ZgU/images/metadata-filters.png?fit=max&auto=format&n=EKxolPDRqqOR-ZgU&q=85&s=50754dd8329748f3c12a73b50dde68b6" width="1365" height="784" data-path="images/metadata-filters.png" />
</Frame>

## Automatic Metadata from Headers (Self-Hosted)

<Info>
  Available on **Enterprise** Self Hosting plan. Requires gateway **2.5.0** or higher.
</Info>

For self-hosted deployments, you can automatically inject request header values into metadata using the `HEADERS_TO_METADATA` environment variable. This is useful for enriching observability data with upstream context without requiring clients to set `x-portkey-metadata`.

```
HEADERS_TO_METADATA=x-request-id,x-caller-service,x-environment
```

When configured, the gateway extracts the specified header values from each incoming request and merges them into the request metadata. Header names are matched case-insensitively.

## Enterprise Features

For enterprise users, Portkey offers advanced metadata governance and lets you define metadata at multiple levels:

1. **Request level** - Applied to a single request
2. **API key level** - Applied to all requests using that key
3. **Workspace level** - Applied to all requests in a workspace

<Card title="Enforcing Required Metadata" href="/product/administration/enforcing-request-metadata">
  Define mandatory metadata fields that must be included with all requests
</Card>

When the same key appears at multiple levels, the **precedence order** is:

1. Workspace metadata (highest priority)
2. API key metadata
3. Request metadata (lowest priority)

<Info>
  Please note that before 1.10.20, the precedence order was:

  1. Request metadata (highest priority)
  2. API key metadata
  3. Workspace metadata (lowest priority)
</Info>

## Best Practices

* Use **consistent keys** across your organization

* Create **naming conventions** for metadata keys

* Consider adding these common fields:
  * `_user`: Who initiated this request
  * `environment`: Which environment (dev/staging/prod)
  * `feature` or `component`: Which part of your product
  * `version`: API or app version
  * `session_id`: To group related requests
  * `request_id`: Your internal tracking ID

* For proper tracking, **always include the `_user` field** when the request is on behalf of an end-user
