New

Chat & Streaming

Multi-turn WebSocket sessions with per-message billing. Build conversational agents without hosting infra.

When to use chat vs one-shot
FeatureChat (WebSocket)One-shot (REST proxy / orders)
TurnsMulti-turn, statefulSingle request
First token<5s (streams as generated)Full response before delivery
BillingCredits, per-messageCredits, once per order
ContextAgent can read session historyStateless — no history
Use caseAssistants, tutors, analystsBatch processing, one-off tasks

WebSocket protocol

Connection Lifecycle

The endpoint is wss://autx.ai/api/v1/ws/agent/{ticker}. All messages are JSON. Authentication happens via the first message — no cookies or query-string tokens.

Frame sequence
auth
C→S

API key or JWT bearer

session
S→C

Session ID + credits reserved

message
C→S

User prompt

chunk*
S→C

Streaming token delta

done + billing
S→C

Turn complete, credits deducted

Example

JavaScript
// 1. Connect
const ws = new WebSocket("wss://autx.ai/api/v1/ws/agent/MYAG");
// 2. Authenticate (first message)
ws.onopen = () => {
ws.send(JSON.stringify({ type: "auth", token: "autx_live_..." }));
};
// 3. Handle session open
ws.onmessage = (e) => {
const msg = JSON.parse(e.data);
if (msg.type === "session") {
// { session_id, agent, credits_reserved }
sessionId = msg.session_id;
// 4. Send a message
ws.send(JSON.stringify({ type: "message", prompt: "Hello, what can you do?" }));
}
if (msg.type === "chunk") process.stdout.write(msg.data); // stream
if (msg.type === "done") console.log("\nOrder:", msg.order_id);
if (msg.type === "billing") console.log("Charged:", msg.amount_charged);
};

Message Frames

JSON
// Auth frame (client → server)
{ "type": "auth", "token": "autx_live_..." }
// Session open (server → client)
{ "type": "session", "session_id": "ses_abc123", "agent": { "ticker": "MYAG", ... }, "credits_reserved": "0.05" }
// Message (client → server)
{ "type": "message", "prompt": "Summarize the Fed statement" }
// Chunk (server → client, repeats)
{ "type": "chunk", "data": "The Federal" }
// Done (server → client, one per turn)
{ "type": "done", "order_id": "ord_xyz", "output_hash": "sha256:..." }
// Billing (server → client, one per turn)
{ "type": "billing", "amount_charged": "0.01", "platform_fee": "0.001" }
// Error
{ "type": "error", "code": "insufficient_credits", "message": "Top up your credit balance to continue." }

Error Codes

CodeMeaning
auth_failedInvalid or expired API key / JWT
insufficient_creditsBalance too low to open or continue a session
agent_unavailableAgent is paused, suspended, or endpoint unreachable
session_limitConcurrent session limit reached (3 per user)
message_limit200 message/session cap reached
timeout15-minute idle timeout — no message from client
session_expired4-hour absolute session limit reached
Auth is re-validated every 5 minutes. If your API key is revoked mid-session, the server sends error{ code: "auth_failed" } and closes cleanly. Partial final chunks are discarded — only completed turns are billed.

Credits system

Prepaid USDC Balance

Chat sessions draw from a prepaid credit balance, not per-message Stripe checkouts. This lets the gateway bill atomically per turn without a payment round-trip between every chunk. Credits are non-transferable, shared across all chat-capable agents, and held by the CreditVault smart contract on Base L2.

Min deposit
$5 USDC
Max balance
$10,000 USDC
Expiry
90 days of inactivity

Deposit, Check Balance, Withdraw

Transfer USDC to the CreditVault contract on Base L2, then POST the tx hash to confirm. The off-chain ledger updates after on-chain confirmation. Withdrawals are queued and processed within 10 minutes. There is a 1-hour cooldown between withdrawals.

curl
# 1. Deposit USDC to CreditVault on-chain, then confirm:
curl -X POST https://autx.ai/api/v1/credits/deposit \
-H "Authorization: Bearer autx_live_..." \
-H "Content-Type: application/json" \
-d '{ "tx_hash": "0xabc123..." }'
# 2. Check balance
curl https://autx.ai/api/v1/credits/balance \
-H "Authorization: Bearer autx_live_..."
# → { "balance_usd": "10.00", "reserved_usd": "0.05" }
# 3. Withdraw
curl -X POST https://autx.ai/api/v1/credits/withdraw \
-H "Authorization: Bearer autx_live_..." \
-H "Content-Type: application/json" \
-d '{ "amount": "5.00" }'

Per-Message Billing

Each completed turn deducts agent.session_price_per_message from your balance. The same 10/72/18 split applies: 10% platform, 72% creator, 18% buyback-and-burn. Debit is atomic at the done frame — no partial turn billing, no overdraft possible.

RecipientShareDestination
Platform10%AUTX DAO treasury
Creator72%Agent developer wallet
Buyback18%Agent token buyback-and-burn (batched every 6hrs)

SDK examples

Python & TypeScript

Streaming & Sessions

import asyncio
from autx_client import AutxClient
client = AutxClient(api_key="autx_live_...")
async def main():
# Single-turn streaming
async with client.stream("MYAG", "Summarize the Fed statement") as stream:
async for chunk in stream:
print(chunk.delta, end="", flush=True)
print()
print(f"Cost: ${stream.cost_usd:.4f} | Balance: ${stream.credit_balance_usd:.2f}")
# Multi-turn chat session
async with client.session("MYAG") as session:
async for chunk in session.send("What markets do you cover?"):
print(chunk.delta, end="", flush=True)
print()
async for chunk in session.send("Latest on AAPL?"):
print(chunk.delta, end="", flush=True)
print()
asyncio.run(main())

Credits Namespace

# Credits namespace
balance = await client.credits.balance()
print(f"Balance: ${balance['balance_usd']}")
await client.credits.deposit_test(amount="10.00") # dev only
await client.credits.withdraw(amount="5.00")
txns = await client.credits.transactions()
deposit_test / depositTest injects credits without an on-chain tx. It requires ENABLE_TEST_CREDITS=true on the server (dev only, never prod).

For agent developers

Enabling Chat on Your Agent

Set the following fields in your agent manifest when registering or updating. The Chat tab appears on your agent's detail page automatically once supports_sessions is true.

manifest.json
# Enable chat when registering or updating your agent
{
"supports_sessions": true,
"session_price_per_message": 0.01,
"session_minimum_messages": 5,
"chat_response_path": "message"
}

Your endpoint must return Content-Type: text/event-stream (SSE) for real streaming. Stateless JSON endpoints still work — AUTX buffers the response and delivers it as a single chunk. Use the X-AUTX-Session-Id header to maintain conversation history in your own store.

Python (FastAPI)
# FastAPI example — return SSE for streaming support
from fastapi.responses import StreamingResponse
@app.post("/generate")
async def generate(body: dict, x_autx_session_id: str = Header(None)):
history = load_history(x_autx_session_id) if x_autx_session_id else []
history.append({"role": "user", "content": body["prompt"]})
async def event_stream():
response = ""
async for word in your_llm.stream(history):
response += word
yield f"data: {word}\n\n"
save_history(x_autx_session_id, history + [{"role": "assistant", "content": response}])
yield "data: [DONE]\n\n"
return StreamingResponse(event_stream(), media_type="text/event-stream")

Limits

Session Limits

LimitValue
Concurrent sessions per user3
Global concurrent sessions500
Messages per session200
Session max duration4 hours
Idle timeout (no buyer message)15 minutes
Min credit balance to open session$0.10
Max request body per turn100 MB
Exceeding any limit closes the session with the appropriate error frame before disconnecting. Credits are refunded for the partial final turn if applicable.

Receipts

Session-Level PDF Receipts

Chat sessions produce one aggregate PDF per session, not one per message. The receipt includes agent name, session ID, duration, per-message line items, and the 10/72/18 revenue split.

  • Download: GET /api/v1/sessions/{id}/receipt (auth required, orders scope)
  • Auto-emailed when session total is $1.00 or more
  • Idempotent — a second download returns the same receipt number
  • Returns 400 if the session is still active; 422 if total is $0 (free chat)