Agent Attribution API Patterns

The Syndicate Links API is designed for machine-to-machine attribution — every endpoint accepts and returns JSON, authenticates via bearer token, and requires no browser interaction. This guide covers the core API patterns for tracking referrals, verifying attribution, and settling commissions.

Authentication

All API requests authenticate with a bearer token. There are two key types:

  • Publisher keys (aff_agent_ prefix) — used by agents to submit attribution events and query commissions
  • Merchant keys (merch_ prefix) — used by merchants to verify conversions and manage programs
curl -H "Authorization: Bearer aff_agent_abc123" \
  https://api.syndicatelinks.co/v1/commissions

Core Endpoints

POST /v1/track — Record an Attribution Event

Submit an attribution event when an agent makes a recommendation. This is the primary tracking endpoint — the equivalent of a "click" in traditional affiliate tracking, but for agents.

curl:

curl -X POST https://api.syndicatelinks.co/v1/track \
  -H "Authorization: Bearer aff_agent_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "event": "recommendation",
    "merchant_id": "merch_xyz",
    "product_id": "prod_456",
    "metadata": {
      "agent_runtime": "langchain",
      "session_id": "sess_789",
      "recommendation_context": "user asked for project management tools"
    }
  }'

Python:

import requests

response = requests.post(
    "https://api.syndicatelinks.co/v1/track",
    headers={"Authorization": "Bearer aff_agent_abc123"},
    json={
        "event": "recommendation",
        "merchant_id": "merch_xyz",
        "product_id": "prod_456",
        "metadata": {
            "agent_runtime": "langchain",
            "session_id": "sess_789"
        }
    }
)

result = response.json()
slat_token = result["slat_token"]
event_id = result["event_id"]

Node.js:

const response = await fetch("https://api.syndicatelinks.co/v1/track", {
  method: "POST",
  headers: {
    "Authorization": "Bearer aff_agent_abc123",
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
    event: "recommendation",
    merchant_id: "merch_xyz",
    product_id: "prod_456",
    metadata: {
      agent_runtime: "langchain",
      session_id: "sess_789"
    }
  })
});

const { slat_token, event_id } = await response.json();

Response:

{
  "event_id": "evt_a1b2c3",
  "slat_token": "slat_v1_...",
  "status": "tracked",
  "created_at": "2026-04-04T10:30:00Z"
}

POST /v1/verify — Confirm a Conversion

Called by the merchant when a purchase is completed. Matches the conversion against a previously tracked attribution event.

curl -X POST https://api.syndicatelinks.co/v1/verify \
  -H "Authorization: Bearer merch_key_xyz" \
  -H "Content-Type: application/json" \
  -d '{
    "order_id": "order_001",
    "amount": 9900,
    "currency": "usd",
    "slat_token": "slat_v1_..."
  }'

Response:

{
  "verification_id": "ver_d4e5f6",
  "status": "verified",
  "commission": {
    "amount": 990,
    "currency": "usd",
    "rate": "10%",
    "publisher_id": "pub_abc"
  }
}

GET /v1/commissions — Query Commission Status

Retrieve commission records for the authenticated publisher.

curl https://api.syndicatelinks.co/v1/commissions \
  -H "Authorization: Bearer aff_agent_abc123" \
  -G -d "status=pending" -d "limit=20"

Response:

{
  "commissions": [
    {
      "id": "com_g7h8i9",
      "amount": 990,
      "currency": "usd",
      "status": "pending",
      "merchant": "Linear",
      "order_id": "order_001",
      "created_at": "2026-04-04T10:30:00Z"
    }
  ],
  "total_pending": 4950,
  "total_approved": 12300,
  "total_paid": 89700
}

POST /v1/payouts — Request a Payout

Trigger a payout for accumulated approved commissions.

curl -X POST https://api.syndicatelinks.co/v1/payouts \
  -H "Authorization: Bearer aff_agent_abc123" \
  -H "Content-Type: application/json" \
  -d '{
    "method": "usdc",
    "address": "0x4808...6D66"
  }'

x402 Attribution Header

For transactions using the x402 payment protocol, attribution is embedded in the HTTP headers rather than submitted as a separate API call:

X-SL-Attribution: atxp_reference=atxp_abc123;agent_key=aff_agent_abc123;ts=1712234400

The atxp_reference token survives the x402 request/retry cycle. The server extracts the attribution data from the header and records it alongside the payment.

Error Handling

All error responses follow a consistent structure:

{
  "error": {
    "code": "invalid_slat_token",
    "message": "The SLAT token signature is invalid or the token has expired",
    "details": {
      "token_age_seconds": 86401,
      "max_age_seconds": 86400
    }
  }
}

Common error codes:

  • invalid_slat_token — token signature validation failed
  • nonce_replay — the token nonce has already been used
  • token_expired — the token timestamp is outside the attribution window
  • merchant_not_found — the specified merchant ID does not exist
  • rate_limited — too many attribution events in the current window

Rate Limits

  • Track events: 100 per minute per agent key
  • Commission queries: 60 per minute per agent key
  • Payout requests: 10 per hour per publisher account

Rate limit headers are included in every response:

X-RateLimit-Limit: 100
X-RateLimit-Remaining: 87
X-RateLimit-Reset: 1712234460