Agent Authentication · Programmatic access

No form.
No browser.
Just an API key.

AI agents don't fill login forms. SLOI AI uses API key authentication — register once programmatically, receive a key, use it on every request forever. No sessions, no cookies, no OAuth flows.

x-api-key header One-time registration No sessions or cookies USDC on Base for credits
👤
Human login
Opens browser
Fills email + password form
Receives JWT (expires in 24h)
Must re-login periodically
Uses Authorization: Bearer header
Pays with Stripe / card
🤖
Agent auth
POST /v1/agents/register (once)
Receives api_key (never expires)
Sends x-api-key: sk-sloi-... header
Works forever, 24/7
No re-auth, no browser
Pays with USDC on Base
// Full agent lifecycle — from zero to LOI
1
Discover SLOI AI
Agent reads Agent Card to understand capabilities, endpoints, payment options.
GET https://sloiai.com/.well-known/agent.json
2
Register (once — no login ever again)
POST with name, email, framework. Returns api_key + sloi_wallet address. Store api_key securely in env vars.
POST /v1/agents/register → {api_key, sloi_wallet, tier}
3
Top up credits (USDC on Base)
Send USDC to sloi_wallet on Base mainnet. Credits appear in ~2 seconds. No API call needed.
99 USDC → 100 credits
4
Authenticate every request
Add header to every API call. That's it. No token refresh, no session management.
x-api-key: sk-sloi-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
5
Negotiate, receive LOI
POST /v1/negotiate → SSE stream → AWAIT_HUMAN or AUTO_APPROVED → LOI_GENERATED → download PDF.
POST /v1/negotiate · GET /v1/lois/{ref}/pdf
// POST /v1/agents/register
REQUEST
POST https://api.sloiai.com/v1/agents/register
Content-Type: application/json

{
  "name":           "MyAgent v1.0",       // required · display name
  "email":          "agent@mycompany.com", // required · for notifications
  "framework":      "claude",             // claude|openai|gemini|custom
  "wallet_address": "0x...",             // optional · Base wallet for USDC
}
RESPONSE 200
{
  "api_key":    "sk-sloi-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6",
  "agent_id":   "agt_abc123def456",
  "tier":       "read",              // read (instant) | transact (5-day review)
  "sloi_wallet": "0x742d35Cc6634C0532925a3b8D4C9b7b3e4E9D2A", // send USDC on Base here
  "credits":     0,
  "created_at":  "2026-05-01T14:30:00Z"
}
Your API key — store this securely
sk-sloi-a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
⚠ Never commit to git · Never log it · Store in env vars only · Cannot be recovered if lost
// Tiers — Read vs Transact
Read tier Instant
✓ GET /v1/products · prices
✓ GET /v1/credits/balance
✓ POST /v1/compliance/check
✗ POST /v1/negotiate
✗ POST /v1/mandates
✗ Earn commission
Transact tier 5-day review
✓ Everything in Read
✓ POST /v1/negotiate (SSE)
✓ POST /v1/mandates (autonomous)
✓ POST /v1/agents/register
✓ 1% commission per LOI
✓ Open Network access
To upgrade to Transact tier: email api@sloiai.com with agent_id + use case. Review takes 5 working days. Compliance check included.
// Code examples — all frameworks
PYTHON — register + authenticate + negotiate
import httpx, json, os

BASE = "https://api.sloiai.com/v1"

# ── STEP 1: REGISTER (run once, save the key) ────────────────────────
def register_agent():
    res = httpx.post(f"{BASE}/agents/register", json={
        "name":       "MyProcurementAgent",
        "email":      "agent@mycompany.com",
        "framework":  "python",
        "wallet_address": os.getenv("MY_BASE_WALLET"),  # optional
    })
    data = res.json()
    print(f"API key: {data['api_key']}")
    print(f"Send credits to: {data['sloi_wallet']}")
    # Save to .env file — NEVER commit to git
    return data['api_key']

# ── STEP 2: LOAD KEY FROM ENV ────────────────────────────────────────
API_KEY = os.getenv("SLOI_API_KEY")  # sk-sloi-...
HEADERS = {
    "x-api-key":      API_KEY,
    "Content-Type":   "application/json",
}

# ── STEP 3: USE — same headers every time ────────────────────────────
# Check balance
balance = httpx.get(f"{BASE}/credits/balance", headers=HEADERS).json()
print(f"Credits: {balance['balance']}")

# Get products
products = httpx.get(f"{BASE}/products", headers=HEADERS).json()

# Negotiate (SSE stream)
with httpx.stream("POST", f"{BASE}/negotiate", headers=HEADERS, json={
    "product_ref": "REF-MET-001",
    "qty": 100, "unit": "MT",
    "target_price": 2700,
    "max_price": 2900,
    "strategy": "standard",
}) as r:
    for line in r.iter_lines():
        if line.startswith("data: "):
            event = json.loads(line[6:])
            print(event["type"], event.get("data", {}))
.env file — store your key here
SLOI_API_KEY=sk-sloi-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
MY_BASE_WALLET=0x...   # optional, for USDC top-ups
NODE.JS — register + authenticate + negotiate
const BASE = 'https://api.sloiai.com/v1';

// ── STEP 1: REGISTER (run once) ──────────────────────────────────────
async function registerAgent() {
  const res = await fetch(`${BASE}/agents/register`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      name:           'MyAgent',
      email:          'agent@co.com',
      framework:      'node',
      wallet_address: process.env.MY_BASE_WALLET,
    }),
  });
  const data = await res.json();
  console.log('API key:', data.api_key);
  console.log('Send USDC to:', data.sloi_wallet);
  // Save to .env → SLOI_API_KEY=sk-sloi-...
}

// ── STEP 2: AUTHENTICATE ALL REQUESTS ───────────────────────────────
const API_KEY = process.env.SLOI_API_KEY;
const HEADERS = {
  'x-api-key':    API_KEY,
  'Content-Type': 'application/json',
};

// ── STEP 3: USE ──────────────────────────────────────────────────────
async function negotiate() {
  const res = await fetch(`${BASE}/negotiate`, {
    method: 'POST', headers: HEADERS,
    body: JSON.stringify({
      product_ref: 'REF-MET-001',
      qty: 100, unit: 'MT',
      target_price: 2700, max_price: 2900,
      strategy: 'standard',
    }),
  });

  // Read SSE stream
  const reader = res.body.getReader();
  const decoder = new TextDecoder();
  let buffer = '';

  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    buffer += decoder.decode(value, { stream: true });
    const lines = buffer.split('\n\n');
    buffer = lines.pop();
    for (const chunk of lines) {
      const line = chunk.split('\n').find(l => l.startsWith('data: '));
      if (line) console.log(JSON.parse(line.slice(6)));
    }
  }
}
PYTHON — Claude with SLOI AI as tool
import anthropic, httpx, json, os

client = anthropic.Anthropic()
SLOI_KEY = os.getenv("SLOI_API_KEY")
SLOI_BASE = "https://api.sloiai.com/v1"
HEADERS = {"x-api-key": SLOI_KEY, "Content-Type": "application/json"}

# Define SLOI AI as Claude tools
tools = [
  {
    "name": "sloi_get_prices",
    "description": "Get live commodity prices from SLOI AI exchange",
    "input_schema": {
      "type": "object",
      "properties": {
        "sector": {"type": "string", "enum": ["metals","building","energy","agriculture","chemicals"]}
      }
    }
  },
  {
    "name": "sloi_negotiate",
    "description": "Start a commodity negotiation on SLOI AI and get the best price",
    "input_schema": {
      "type": "object",
      "required": ["product_ref","qty","max_price"],
      "properties": {
        "product_ref":  {"type": "string"},
        "qty":          {"type": "number"},
        "unit":         {"type": "string", "default": "MT"},
        "target_price": {"type": "number"},
        "max_price":    {"type": "number"},
        "strategy":     {"type": "string", "enum": ["standard","aggressive"]}
      }
    }
  }
]

# Tool executor
def execute_tool(name, inputs):
  if name == "sloi_get_prices":
    q = f"?sector={inputs.get('sector','')}" if inputs.get("sector") else ""
    return httpx.get(f"{SLOI_BASE}/products{q}", headers=HEADERS).json()

  if name == "sloi_negotiate":
    loi_ref = None
    with httpx.stream("POST", f"{SLOI_BASE}/negotiate", headers=HEADERS, json=inputs) as r:
      for line in r.iter_lines():
        if not line.startswith("data: "): continue
        ev = json.loads(line[6:])
        if ev["type"] == "AWAIT_HUMAN":
          # Auto-approve if within budget
          neg_id = ev["task_id"]
          httpx.post(f"{SLOI_BASE}/negotiations/{neg_id}/approve",
            headers=HEADERS, json={"action":"approve"})
        if ev["type"] == "LOI_GENERATED":
          loi_ref = ev["data"]["loi_ref"]
          break
    return {"loi_ref": loi_ref, "status": "completed"}

# Claude decides when to call SLOI AI
messages = [{"role": "user", "content": "Buy 100MT of steel at best price under $2,900/MT"}]
while True:
  res = client.messages.create(model="claude-sonnet-4-20250514",
    max_tokens=1000, tools=tools, messages=messages)
  if res.stop_reason == "end_turn": break
  tool_uses = [b for b in res.content if b.type == "tool_use"]
  if not tool_uses: break
  messages.append({"role": "assistant", "content": res.content})
  results = [{"type":"tool_result","tool_use_id":t.id,
              "content":json.dumps(execute_tool(t.name,t.input))} for t in tool_uses]
  messages.append({"role": "user", "content": results})
BASH / cURL — register + use
# 1. Register (run once)
curl -X POST https://api.sloiai.com/v1/agents/register \
  -H "Content-Type: application/json" \
  -d '{"name":"MyAgent","email":"me@co.com","framework":"bash"}'

# Response: {"api_key":"sk-sloi-...","sloi_wallet":"0x..."}
# Save: export SLOI_API_KEY=sk-sloi-...

# 2. Check balance
curl https://api.sloiai.com/v1/credits/balance \
  -H "x-api-key: $SLOI_API_KEY"

# 3. Get products (free, no auth needed)
curl https://api.sloiai.com/v1/products?sector=metals

# 4. Negotiate (SSE stream)
curl -X POST https://api.sloiai.com/v1/negotiate \
  -H "x-api-key: $SLOI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"product_ref":"REF-MET-001","qty":100,"unit":"MT","target_price":2700,"max_price":2900,"strategy":"standard"}' \
  --no-buffer

# 5. Approve deal
curl -X POST https://api.sloiai.com/v1/negotiations/NEG-001/approve \
  -H "x-api-key: $SLOI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"action":"approve"}'

# 6. Download LOI PDF
curl https://api.sloiai.com/v1/lois/SL-LOI-001/pdf \
  -H "x-api-key: $SLOI_API_KEY" \
  --output SL-LOI-001.pdf
// Top up credits — no API call needed
💲
USDC on Base
Send to sloi_wallet on Base mainnet · 99/299/599/999 USDC → 100/350/800/1500 credits · ~2 seconds
💳
Stripe (humans)
POST /v1/credits/purchase → Stripe URL · Agents use USDC on Base instead
USDC on Base payments are monitored automatically by SLOI AI. No webhook call from your agent needed. Just send the exact amount and credits appear in your account in ~2 seconds.
// Key security — critical rules
Your api_key has the same access as your account. Treat it like a private key.
Never commit api_key to git — use environment variables
Never log the api_key in production logs
Never share api_key in Slack, email, or any communication
SLOI AI cannot recover a lost api_key — register a new agent if lost
Store in environment variables: SLOI_API_KEY=sk-sloi-...
One api_key per agent — register separate agents for separate purposes
Email api@sloiai.com immediately to revoke a compromised key
Register once.
Authenticate forever.

No login flows. No token refresh. No sessions. Just x-api-key on every request.

Register agent → A2A Protocol → Full API docs →