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

# Request metadata

> Attach an app name, identity, thread, tags, and custom metadata to AI Gateway requests, and slice traces and analytics by the mechanism that answers each question.

**Use Cases**

<AccordionGroup>
  <Accordion title="Attribute requests to an app or service">
    Name each request so cost and performance slice by product, feature, or environment.
  </Accordion>

  <Accordion title="Group analytics by end user or tenant">
    Attach an **Identity** so spend, latency, and error rates attribute to a user, team, or client, with optional per-identity budgets.
  </Accordion>

  <Accordion title="Group multi-turn conversations">
    Tag each turn with a **Thread** ID so the full conversation groups together in observability.
  </Accordion>

  <Accordion title="Slice analytics by business context">
    Attach key-value metadata, such as tier, channel, or feature flag, and filter traces by those fields.
  </Accordion>
</AccordionGroup>

## Overview

Every **AI Gateway** request can carry context through several mechanisms:

* `name`: marks the app or service
* `identity`: marks the end user or tenant
* `thread`: groups a conversation
* `metadata`: carries business context
* `tags`: adds grouping labels

Each mechanism answers one question and surfaces through its own channel. Use the decision table below to pick the mechanism for a given question.

`variables` also travel with the request, but fill prompt templates instead of describing the request. The how-to for each mechanism lives in [App Tracking](/docs/ai-gateway/app-tracking), [Identities](/docs/ai-studio/observability/identities), and [Thread Management](/docs/ai-gateway/thread-management); the span attribute reference is in [Metadata](/docs/ai-gateway/orq-attributes).

## Which mechanism to use

| Mechanism  | Answers the question                                        | Use when                                                                                        |
| ---------- | ----------------------------------------------------------- | ----------------------------------------------------------------------------------------------- |
| `name`     | Which app, service, or feature made this call?              | Cost and performance per product line, with a fixed set of known surfaces                       |
| `identity` | Which end user, team, or client is this request for?        | Per-user attribution, tenant billing, per-identity budgets                                      |
| `thread`   | Which conversation or workflow does this request belong to? | Multi-turn chats, multi-step agent workflows, support tickets                                   |
| `metadata` | What business context applies to this request?              | Key-value slicing by tier, channel, region, or feature flag                                     |
| `tags`     | Which labels group these requests?                          | Grouping across apps, users, or conversations, for example `support`, `premium`, `experiment-a` |

## Quick Start

Send one request with all five mechanisms attached.

<CodeGroup>
  ```bash cURL theme={"theme":{"light":"github-light","dark":"github-dark"}}
  curl -X POST https://api.orq.ai/v3/router/responses \
    -H "Authorization: Bearer $ORQ_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "openai/gpt-5.4-mini",
      "input": "Refund my order",
      "name": "SupportAssistant-Production",
      "metadata": {
        "customer_tier": "premium",
        "channel": "email"
      },
      "tags": ["support", "refund"],
      "thread": {
        "id": "conversation-abc123",
        "tags": ["user-123"]
      },
      "identity": {
        "id": "user_123"
      }
    }'
  ```

  ```typescript TypeScript theme={"theme":{"light":"github-light","dark":"github-dark"}}
  import OpenAI from "openai";

  const client = new OpenAI({
    apiKey: process.env.ORQ_API_KEY,
    baseURL: "https://api.orq.ai/v3/router",
  });

  const response = await client.responses.create({
    model: "openai/gpt-5.4-mini",
    input: "Refund my order",
    name: "SupportAssistant-Production",
    metadata: { customer_tier: "premium", channel: "email" },
    tags: ["support", "refund"],
    thread: { id: "conversation-abc123", tags: ["user-123"] },
    identity: { id: "user_123" },
  });

  console.log(response.output_text);
  ```

  ```python Python theme={"theme":{"light":"github-light","dark":"github-dark"}}
  from openai import OpenAI
  import os

  client = OpenAI(
      api_key=os.environ.get("ORQ_API_KEY"),
      base_url="https://api.orq.ai/v3/router",
  )

  response = client.responses.create(
      model="openai/gpt-5.4-mini",
      input="Refund my order",
      extra_body={
          "name": "SupportAssistant-Production",
          "metadata": {"customer_tier": "premium", "channel": "email"},
          "tags": ["support", "refund"],
          "thread": {"id": "conversation-abc123", "tags": ["user-123"]},
          "identity": {"id": "user_123"},
      },
  )

  print(response.output_text)
  ```
</CodeGroup>

## Configuration

| Parameter   | Type      | Required | Description                                                                                                                      |
| ----------- | --------- | -------- | -------------------------------------------------------------------------------------------------------------------------------- |
| `name`      | string    | No       | Display name on the trace. Recommended: alphanumeric and hyphens only, under 50 characters, no timestamps or dynamic values.     |
| `metadata`  | object    | No       | Key-value pairs with string values. On the **Responses API**, non-string values are rejected with a 400.                         |
| `tags`      | string\[] | No       | Labels for filtering and reporting.                                                                                              |
| `thread`    | object    | No       | Groups related requests: `id` (required) plus optional `tags`.                                                                   |
| `identity`  | object    | No       | Attributes the request to an end user: `id` (required) plus optional `display_name`, `email`, `metadata`, and `tags`.            |
| `variables` | object    | No       | Template variables for prompt substitution. Pass secrets as `{"secret": true, "value": "..."}` so they are redacted from traces. |

<Note>
  On `/v2/router/chat/completions`:

  * `metadata` is limited to 16 key-value pairs with keys up to 64 characters and values up to 512 characters
  * `thread`, `identity`, and `tags` are passed under the `orq` object (`orq.thread`, `orq.identity`, `orq.tags`)
  * `name` is passed at the top level
</Note>

## Where each mechanism surfaces

| Mechanism  | Request field | Span attributes                    | Traces filter                   | Reporting API             |
| ---------- | ------------- | ---------------------------------- | ------------------------------- | ------------------------- |
| `name`     | `name`        | Span name, `gen_ai.operation.name` | Name                            | Not available             |
| `identity` | `identity`    | `orq.identity_id`                  | Identity                        | `identity` dimension      |
| `thread`   | `thread`      | `orq.thread_id`                    | Thread ID                       | `thread` entity dimension |
| `metadata` | `metadata`    | `metadata.<key>`                   | Metadata                        | Not available             |
| `tags`     | `tags`        | `orq.tags`                         | Via span attribute (`orq.tags`) | `tag` entity dimension    |

<Note>
  Filter names follow the [Traces](/docs/ai-studio/observability/traces) page. Custom metadata surfaces as `metadata.<key>` span attributes on router requests, and as an `orq.metadata` JSON attribute on agent and gateway-client spans. See [Metadata](/docs/ai-gateway/orq-attributes) for the full reference.
</Note>

## Best Practices

* **Keep app names low-cardinality**: Use a small fixed set of app names (around 50 per workspace) with consistent patterns such as `Service-Environment`. Avoid timestamps or dynamic values, which fragment analytics.
* **Use a fixed metadata key set**: Define a small set of keys (`customer_tier`, `channel`, `region`) and reuse them. High-cardinality keys, such as request IDs or timestamps, defeat filtering and increase storage.
* **Thread IDs**: Use UUIDs or composite keys such as `user-{userId}-{sessionId}` to avoid collisions across sessions.
* **Identity IDs**: Use predictable patterns such as `user-{userId}` or `tenant-{tenantId}` so identities stay consistent across requests.
* **One mechanism per question**: If the value describes the app, use `name`; if it describes the user, use `identity`; if it is business context, use `metadata`.

## What not to store in request metadata

* **PII**: Do not put emails, phone numbers, or personal data in `metadata`, `name`, or `tags`; they persist on stored traces. To keep sensitive values out of stored traces, include `"metadata"` in [`security.mask`](/docs/ai-gateway/features/security), or enable [PII Redaction](/docs/ai-gateway/features/plugins/pii-redaction).
* **Secrets**: Pass tokens and keys as template variables with `{"secret": true, "value": "..."}` so they are redacted from traces. See [Run Agents](/docs/ai-studio/ai-engineering/run-agents) for the variable reference.
