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

# Metadata

> Attach business context to every request — environment, feature, session, tenant — and slice logs on it.

Metadata lets you attach arbitrary key/value tags to any gateway request. The gateway stores them on the log entry, so you can filter, debug, and analyze traffic by business dimensions instead of raw model IDs.

## How it works

Send a `metadata` object in the request body. It never reaches the provider — the gateway strips it before forwarding and stores it on the [log entry](/dashboard/logs):

```json theme={null}
{
  "model": "openai/gpt-4o",
  "messages": [{"role": "user", "content": "Summarize this ticket"}],
  "metadata": {
    "environment": "production",
    "feature": "doc-summariser",
    "session_id": "sess_123",
    "tenant_id": "acme-corp",
    "plan": "enterprise"
  }
}
```

### Rules

| Constraint   | Value                                                                                |
| ------------ | ------------------------------------------------------------------------------------ |
| Value types  | `string`, `number`, or `boolean` — nested objects and arrays are rejected with a 400 |
| Key length   | 64 characters max, non-empty                                                         |
| Value length | 128 characters max per string value                                                  |
| Keys         | 100 max per request                                                                  |

## Tracking users

Two separate mechanisms, like the industry-standard gateways:

* **`user`** (body field) — the standard OpenAI field. Forwarded to the provider unchanged, and used as the logged end-user ID when no other value is present.
* **`endUserId`** (token claim or `x-gatelit-end-user-id` header) — Gatelit-only, never sent to the provider. Wins over `user` when both are present.

For the full channel inventory and why attributes live where they do, see [Conventions](/gateway/conventions).

## Filtering logs

The dashboard logs page filters on metadata tags with operators. Multiple conditions can be chained — they are combined with AND:

| Operator        | Example                      | Matches                                                     |
| --------------- | ---------------------------- | ----------------------------------------------------------- |
| `equals`        | `environment` = `production` | Exact value match (numbers/booleans match their typed form) |
| `contains`      | `feature` contains `summar`  | Value contains the text (substring)                         |
| `exists`        | `session_id` exists          | Key present, any value                                      |
| `doesn't exist` | `session_id` doesn't exist   | Key absent                                                  |
| `is empty`      | `feature` is empty           | Key present with empty-string value                         |
| `is not empty`  | `feature` is not empty       | Key present with non-empty value                            |

Example chain: `environment` equals `production` **and** `feature` contains `summar` — only requests carrying both tags match.

Notes:

* `contains` treats `%` and `_` as wildcards (SQL `ILIKE` semantics)
* Keys with special characters (dots, quotes, spaces) can only be used with `equals` — the other operators address keys as a single path segment
* Conditions that are only partially filled in (e.g. `equals` without a value) are ignored until completed

## Common patterns

| Use case                 | Example keys                            |
| ------------------------ | --------------------------------------- |
| Environment segmentation | `environment`, `region`, `deployment`   |
| Feature cost attribution | `feature`, `team`, `version`            |
| Multi-tenant SaaS        | `tenant_id`, `tenant_plan`              |
| Session tracking         | `session_id`, `turn`                    |
| Internal tracing         | `request_id`, `service`, `caller`       |
| Prompt experiments       | `experiment`, `variant`                 |
| Compliance / audit       | `user_role`, `data_class`, `regulation` |

## SDK

The TypeScript SDK exposes `metadata` and `user` on `ChatOptions`:

```ts theme={null}
const response = await client.chat({
  model: "openai/gpt-4o",
  messages: [{ role: "user", content: "Summarize this ticket" }],
  metadata: {
    environment: "production",
    feature: "doc-summariser",
    session_id: "sess_123",
  },
  user: "customer_42",
})
```

## Security

Metadata is visible to dashboard users with access to the org's logs. Never put secrets, full PII, or credentials in metadata — use opaque identifiers and classification labels.
