Signed Attribution Tokens (SLAT)
A SLAT (Syndicate Links Attribution Token) is a cryptographically signed, short-lived token that binds a single conversion event to a specific agent identity. SLATs replace cookies as the attribution mechanism in agent commerce — they are minted by the referring agent, submitted with the attribution event, and validated server-side to confirm the referral is legitimate.
Token Structure
A SLAT token is a base64url-encoded JSON payload with an appended HMAC-SHA256 signature. The decoded structure:
{
"v": "slat_v1",
"agent_key": "aff_agent_abc123",
"nonce": "550e8400-e29b-41d4-a716-446655440000",
"ts": 1712234400,
"order_ref": "order_001",
"merchant_id": "merch_xyz"
}
Field Definitions
| Field | Type | Description |
|---|---|---|
v | string | Token version. Current: slat_v1 |
agent_key | string | The aff_agent_ key that is claiming attribution |
nonce | string | UUID v4 — unique per token, used for replay protection |
ts | integer | Unix timestamp (seconds) when the token was minted |
order_ref | string | Order or session identifier linking to the conversion |
merchant_id | string | The merchant program the referral targets |
Signature
The signature is computed as:
HMAC-SHA256(agent_secret, base64url(payload))
Where agent_secret is the secret component of the aff_agent_ key pair. The full token is:
slat_v1_<base64url(payload)>.<base64url(signature)>
Minting a Token
Tokens are minted client-side by the agent at the moment of recommendation. The agent holds the aff_agent_ key and its associated secret.
Python example:
import json
import hmac
import hashlib
import base64
import uuid
import time
def mint_slat(agent_key, agent_secret, merchant_id, order_ref=None):
payload = {
"v": "slat_v1",
"agent_key": agent_key,
"nonce": str(uuid.uuid4()),
"ts": int(time.time()),
"order_ref": order_ref or "",
"merchant_id": merchant_id
}
payload_b64 = base64.urlsafe_b64encode(
json.dumps(payload).encode()
).decode().rstrip("=")
signature = hmac.new(
agent_secret.encode(),
payload_b64.encode(),
hashlib.sha256
).digest()
sig_b64 = base64.urlsafe_b64encode(signature).decode().rstrip("=")
return f"slat_v1_{payload_b64}.{sig_b64}"
Node.js example:
import crypto from "crypto";
import { v4 as uuidv4 } from "uuid";
function mintSlat(agentKey, agentSecret, merchantId, orderRef = "") {
const payload = {
v: "slat_v1",
agent_key: agentKey,
nonce: uuidv4(),
ts: Math.floor(Date.now() / 1000),
order_ref: orderRef,
merchant_id: merchantId,
};
const payloadB64 = Buffer.from(JSON.stringify(payload))
.toString("base64url");
const signature = crypto
.createHmac("sha256", agentSecret)
.update(payloadB64)
.digest("base64url");
return `slat_v1_${payloadB64}.${signature}`;
}
Validation Flow
Server-side validation follows these steps in order:
- Parse — split the token into payload and signature components
- Verify signature — recompute HMAC-SHA256 using the agent's registered secret and compare against the submitted signature
- Check version — confirm
visslat_v1(or a supported version) - Check timestamp — confirm
tsis within the attribution window (default: 24 hours) - Check nonce — confirm the
noncehas not been used before (replay protection) - Match agent key — confirm the
agent_keyis registered and active - Record nonce — store the nonce to prevent future replay
If any step fails, the token is rejected with a specific error code (invalid_signature, token_expired, nonce_replay, agent_key_inactive).
Replay Protection
The UUID v4 nonce ensures each SLAT token can only be used once. After successful validation, the nonce is stored in a server-side set. Any subsequent submission of the same nonce is rejected as a replay.
Nonce storage is time-bounded — nonces older than the maximum attribution window (default: 7 days) are automatically pruned, keeping the storage set manageable even at high volume.
Attribution Window
The ts field determines when the token was minted. The server rejects tokens where current_time - ts exceeds the attribution window. Default windows:
| Window | Duration | Use Case |
|---|---|---|
| Standard | 24 hours | Product recommendations, shopping agents |
| Extended | 7 days | SaaS evaluations, B2B purchasing cycles |
| Immediate | 1 hour | x402 payment flows (attribution and payment are near-simultaneous) |
Merchants can configure custom attribution windows per program.
x402 Integration
In x402 payment flows, the SLAT token is not submitted as a separate API call. Instead, the atxp_reference — a protocol-level attribution identifier — is carried in the X-SL-Attribution HTTP header:
X-SL-Attribution: atxp_reference=slat_v1_...<token>...;agent_key=aff_agent_abc123
The server extracts the SLAT from the header and validates it alongside the payment processing. Attribution and payment settlement happen atomically.
Related Docs
- How Agent Attribution Works — the full technical spec including key issuance and commission flow
- Machine-to-Machine Attribution — how SLAT fits into the broader attribution architecture
- Agent Key Management — managing the keys used to sign SLAT tokens