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

# Request Tags

> Label proxy requests by feature, customer segment or anything else, and filter their events by label

Add an `X-PromptGuard-Tag-<name>` header to a proxy request to label it. Every security event the request produces records the tag, and the dashboard can show you only the events with a given tag. Use tags to tell features, customer segments, environments or experiments apart.

```javascript theme={"system"}
const completion = await client.chat.completions.create(
  {
    model: "gpt-4o",
    messages: [{ role: "user", content: "Summarise this ticket." }],
  },
  {
    headers: {
      "X-PromptGuard-Tag-Feature": "ticket-summary",
      "X-PromptGuard-Tag-Customer-Tier": "enterprise",
    },
  },
);
```

```python theme={"system"}
completion = client.chat.completions.create(
    model="gpt-4o",
    messages=[{"role": "user", "content": "Summarise this ticket."}],
    extra_headers={
        "X-PromptGuard-Tag-Feature": "ticket-summary",
        "X-PromptGuard-Tag-Customer-Tier": "enterprise",
    },
)
```

```bash theme={"system"}
curl https://api.promptguard.co/api/v1/chat/completions \
  -H "X-API-Key: $PROMPTGUARD_API_KEY" \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -H "X-PromptGuard-Tag-Feature: ticket-summary" \
  -H "X-PromptGuard-Tag-Customer-Tier: enterprise" \
  -H "Content-Type: application/json" \
  -d '{"model": "gpt-4o", "messages": [{"role": "user", "content": "Summarise this ticket."}]}'
```

Tags work on every proxy route: `/api/v1/chat/completions`, `/api/v1/messages`, `/api/v1/responses` and `/api/v1/messages/count_tokens`.

## Where tags are stored

Each event the request produces stores its tags in `event_metadata.tags`, as a list of `name:value` strings sorted by name. The request above is stored as:

```json theme={"system"}
{ "tags": ["customer-tier:enterprise", "feature:ticket-summary"] }
```

Every event the request writes, whether from the input scan, the output scan or another check, carries the same tags. An event from a request with no tags has no `tags` key.

A tag name is case-insensitive, like any header name, and is stored in lowercase. `X-PromptGuard-Tag-Feature` and `x-promptguard-tag-feature` are the same tag. A value is stored exactly as you sent it.

## Filter events by a tag

On a project's **Requests** page, type a tag as `name:value` into **Filter by tag**, or select a tag on an event's detail. The list then shows only events with that tag. The tag is saved in the page URL, so you can share or bookmark the filtered list.

Through the API, pass the same `name:value` as the `tag` parameter:

```bash theme={"system"}
curl -H "Authorization: Bearer $TOKEN" \
  "https://api.promptguard.co/dashboard/interactions?project_id=$PROJECT_ID&tag=feature:ticket-summary"
```

A `tag` that is not `name:value` is refused with a `422`.

## Tags are not scanned, and your provider never sees them

PromptGuard scans the request body. Tags are headers, so they never reach a detector: a tag cannot cause a block, and a tag value is not checked for personal data or secrets. PromptGuard also removes every tag header before it forwards the request, so your provider never receives them.

Because tags are not scanned or masked, do not put personal data in them. Tags are stored even when a project has zero retention, like the [`X-End-User`](/gateway/end-users) label. To group by customer, use an internal customer ID, not an email address.

On a [Hybrid](/shadow-ai/deployment-modes) install with `FORWARD_MODE=metadata` (the default), tags stay on your servers and are not sent to the PromptGuard dashboard. With `FORWARD_MODE=content`, they are sent with the rest of the event.

## Limits

* At most 16 tags per request.
* A tag name can be up to 64 characters: letters, digits, `-` and `.`, starting with a letter or digit. Use `-` to separate words, as in `X-PromptGuard-Tag-Feature-Flag`, not `_`: many proxies, including nginx by default, silently drop a header with an underscore in its name, so PromptGuard refuses one rather than let a tag vanish on the way.
* A tag value can be up to 200 characters of printable ASCII, colons included. An empty value is not allowed: leave the header out instead.
* Each tag name can be sent only once per request.

A request with a tag that breaks a limit is refused with a `400` and the error code `invalid_header`, before anything is scanned or sent to your provider. The `param` names the header, or `X-PromptGuard-Tag-*` when there are too many tags:

```json theme={"system"}
{
  "error": {
    "message": "X-PromptGuard-Tag-feature: a tag value is at most 200 characters",
    "type": "invalid_request_error",
    "code": "invalid_header",
    "param": "X-PromptGuard-Tag-feature"
  }
}
```

The limits match common practice: OpenAI's request `metadata` allows 16 pairs with keys up to 64 characters, and Datadog allows tags up to 200 characters.

Send tags from your server. Browser code cannot send them, because the proxy accepts browser requests only from PromptGuard's own sites.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.