---
title: "Identity Headers"
description: "Every drain request carries User-Agent and X-Evlog-Source so receivers can triage the traffic. Override or suppress them when you need to."
canonical_url: "https://www.evlog.dev/extend/identity-headers"
---
# Identity Headers

> Every drain request carries User-Agent and X-Evlog-Source so receivers can triage the traffic. Override or suppress them when you need to.

Every drain request sent by evlog is tagged with two identity headers so receivers can identify the traffic:

<table>
<thead>
  <tr>
    <th>
      Header
    </th>
    
    <th>
      Value
    </th>
  </tr>
</thead>

<tbody>
  <tr>
    <td>
      <code>
        User-Agent
      </code>
    </td>
    
    <td>
      <code>
        evlog/<version>
      </code>
      
       (Node / server runtimes only — browsers strip this header)
    </td>
  </tr>
  
  <tr>
    <td>
      <code>
        X-Evlog-Source
      </code>
    </td>
    
    <td>
      The adapter name (<code>
        axiom
      </code>
      
      , <code>
        datadog
      </code>
      
      , <code>
        otlp
      </code>
      
      , <code>
        posthog
      </code>
      
      , <code>
        sentry
      </code>
      
      , <code>
        better-stack
      </code>
      
      , <code>
        client
      </code>
      
      , …)
    </td>
  </tr>
</tbody>
</table>

The browser-side `evlog/http` drain (used by client logging) sets `X-Evlog-Source: client` instead, since browsers cannot override `User-Agent`.

## Why

- **Triage at the receiver.** Quickly distinguish evlog traffic from other clients in the receiving system's logs.
- **Track adapter usage and version drift.** Roll out a new evlog version and watch the `User-Agent` distribution change centrally.
- **Debug a specific drain.** Filter by `X-Evlog-Source` to isolate one adapter's behavior in a sea of incoming requests.

## Reading the version

Both constants are exported from `evlog/toolkit` so your drain (or your receiver) can reference the canonical values:

```ts
import { EVLOG_USER_AGENT, EVLOG_VERSION } from 'evlog/toolkit'

console.log(EVLOG_VERSION)    // → "2.16.0"
console.log(EVLOG_USER_AGENT) // → "evlog/2.16.0"
```

## Overriding from a custom drain

Adapters built with [`defineHttpDrain()`](https://www.evlog.dev/extend/custom-drains) automatically pass the drain `name` as `source` and the canonical `evlog/<version>` as `userAgent`. You don't need to think about it.

When you build a drain on top of `httpPost` from `evlog/toolkit` directly (e.g. for a fork with a different identity, or for a vendor that wants its own UA), pass `source` and/or `userAgent` to override:

```ts
import { httpPost } from 'evlog/toolkit'

await httpPost({
  url: 'https://my-platform.example.com/ingest',
  headers: { 'Content-Type': 'application/json' },
  body: '[]',
  timeout: 5000,
  label: 'my-platform',
  source: 'my-platform',           // sent as X-Evlog-Source
  userAgent: 'my-fork/1.0',        // overrides the default User-Agent
  // userAgent: false,             // suppress the header entirely
})
```

## Next steps

- [Custom Drains](https://www.evlog.dev/extend/custom-drains): `defineHttpDrain` injects identity headers automatically
- [Drain Pipeline](https://www.evlog.dev/extend/drain-pipeline): wrap any drain in batch + retry while keeping identity headers

---

- [Custom Drains](https://www.evlog.dev/extend/custom-drains)


## Sitemap

See the full [sitemap](https://www.evlog.dev/sitemap.md) for all pages.
