LLMs.txt: agent-readable Markdown index of this site at /llms.txt

Agent Attribution (X-Agent-Info)

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.

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 headers, with a JSON object value containing up to three fields:

FieldTypeRequiredNotes
decision_originstringYesMust be exactly autonomous or human_mediated (case-sensitive). Any other value marks the header malformed.
integration_namestringNoName of your integration or agent, e.g. my-trading-bot. Up to 256 UTF-16 code units, which is JavaScript's String#length.
versionstringNoVersion 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.

# 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 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.

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.