# Agent Attribution (X-Agent-Info) (/docs/trading/swapping-api/start-building/agent-attribution)

Send the optional X-Agent-Info header to attribute agent-driven Trading API traffic, and check x-agent-info-status to confirm it was recognized.

The Uniswap API accepts an optional `X-Agent-Info` request header. Send it if an AI agent built or operates your integration. It lets us measure agent-driven traffic separately from human-driven traffic.

> [!NOTE]
> **Optional, and never affects the request**
>
> `X-Agent-Info` is purely for analytics. Humans and human-facing clients can ignore it entirely. Omitting it, sending it, or sending it incorrectly has no effect on your request. It never changes the response status, body, or any swap behavior.

## Sending the header
Send `X-Agent-Info` alongside your usual [authentication](/docs/trading/swapping-api/start-building/integration-guide#authentication) headers, with a JSON object value containing up to three fields:

| Field              | Type   | Required | Notes                                                                                                                         |
| ------------------ | ------ | -------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `decision_origin`  | string | Yes      | Must be exactly `autonomous` or `human_mediated` (case-sensitive). Any other value marks the header malformed.                |
| `integration_name` | string | No       | Name of your integration or agent, e.g. `my-trading-bot`. Up to 256 UTF-16 code units, which is JavaScript's `String#length`. |
| `version`          | string | No       | Version identifier for your integration. Up to 256 UTF-16 code units.                                                         |

Send only these three fields. Any other key is dropped rather than rejected, so an extra key never makes the header malformed.

`integration_name` and `version` are stored per request and queried later. Both must be stable strings that describe your software. Never send a user ID, wallet address, email address, session token, API key, or any value derived from an end user. On our side, a malformed header is never echoed back or logged, and only the three fields above ever reach our analytics.

```bash
# Fill in your own token addresses and amount. The header is evaluated either way.
curl -X POST https://trade-api.gateway.uniswap.org/v1/quote \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -H 'X-Agent-Info: {"decision_origin":"autonomous","integration_name":"my-trading-bot","version":"1.4.0"}' \
  -d '{"tokenIn":"0x...","tokenOut":"0x...","tokenInChainId":1,"tokenOutChainId":1,"type":"EXACT_INPUT","amount":"1000000","swapper":"0x...","slippageTolerance":0.5}'
```

## What makes a header malformed
A header is dropped (marked malformed) rather than rejected outright if any of the following hold. The request is handled exactly as if the header were absent. See [Confirming it was received](#confirming-it-was-received) below for how to tell the difference.

* The raw header value is larger than **1024 bytes**, measured on the raw value before parsing. JSON whitespace and `\u` escapes count toward the cap.
* The raw header value contains any byte outside printable US-ASCII (`0x20`–`0x7E`). This is checked first, before the JSON is parsed, because bytes above `0x7E` decode differently in different HTTP stacks. So a literal `é`, an emoji, or a curly quote in the header marks it malformed no matter how short the value is. Send non-ASCII as a JSON `\u` escape instead.
* The value isn't valid JSON, or is valid JSON that isn't a plain object (an array, string, number, boolean, or `null`).
* The request carried two or more `X-Agent-Info` header lines. They are joined with `", "`, which is almost never valid JSON. Set the header once rather than appending to it, since some HTTP clients append by default.
* `decision_origin` is missing, or is anything other than exactly `autonomous` or `human_mediated`.
* `integration_name` or `version` is present but isn't a string, or is longer than 256 UTF-16 code units. That count is JavaScript's `String#length`, so an emoji or other astral character costs two units, not one.
* `integration_name` or `version` contains a disallowed character. Those are control characters (C0 `0x00`–`0x1F`, DEL `0x7F`, C1 `0x80`–`0x9F`), the Unicode line separators U+2028 and U+2029, and the replacement character U+FFFD. An escaped unpaired surrogate decodes to U+FFFD, so it is rejected too. Text pasted from a PDF, or left behind by a lossy re-encode, often carries one of these invisibly.

Not sending the header at all isn't an error condition. It's simply "no attribution," the same outcome as a header that's out of scope for your client.

## Confirming it was received
Because the request succeeds regardless of whether `X-Agent-Info` parsed, check the `x-agent-info-status` response header to confirm your header was actually recognized:

* **`x-agent-info-status: malformed`**: the header was received but failed one of the checks above and was dropped. The value is always the fixed string `malformed`; it never echoes anything from your request.
* **No `x-agent-info-status` header at all**: your `X-Agent-Info` header parsed, or you didn't send one.

The gateway sets this header after it routes your request, and before it writes its own response. Error responses carry it too: a 400, a 401, a 403, a 429, and a 404 for a path that does not exist. So you can debug the header without first getting a working quote. A CORS preflight carries no status header, because the gateway answers it before it looks at `X-Agent-Info`.

Call the Trading API server-to-server. The gateway sends CORS headers only to a small allow-list of origins, so a browser page on your own domain cannot read this header. Check it from a server or with curl.

```typescript
const response = await fetch('https://trade-api.gateway.uniswap.org/v1/quote', {
  method: 'POST',
  headers: {
    'x-api-key': 'YOUR_API_KEY',
    'Content-Type': 'application/json',
    Accept: 'application/json',
    'X-Agent-Info': JSON.stringify({
      decision_origin: 'autonomous',
      integration_name: 'my-trading-bot',
      version: '1.4.0',
    }),
  },
  body: JSON.stringify({
    tokenIn: '0x...',
    tokenOut: '0x...',
    tokenInChainId: 1,
    tokenOutChainId: 1,
    type: 'EXACT_INPUT',
    amount: '1000000',
    swapper: '0x...',
    slippageTolerance: 0.5,
  }),
});

if (response.headers.get('x-agent-info-status') === 'malformed') {
  // Received but dropped. Check field names, decision_origin value, and length limits above.
  console.warn('X-Agent-Info was sent but not recognized.');
}

const quote = await response.json();
```

The only consequence of a malformed header is that your traffic isn't attributed to your integration.
