API Documentation

Everything you need to integrate the Fauri AI agent into your platform

How It Works

Fauri is the platform — merchants supply products, the AI agent powers shopping. You integrate it into your app.

Fauri Platform

Supply Side

Merchants

Shopify, WooCommerce

Shopify API

Product Sync

Auto-import catalog

Unified Catalog

All products indexed

Merchants connect their stores. Products, variants, prices, and inventory are synced automatically into Fauri's unified catalog.

AI Engine

AI Agent

Powered by Claude

Smart Search

Semantic matching

Conversation

Natural language

Claude-powered AI agent understands natural language, searches across all merchant catalogs, recommends products, and handles the full purchase flow.

REST API + WebSocket
Your Application

Your App

Gets API keys

Embed

Chat Widget

In your UI

Users arrive

End Users

Your customers

You integrate Fauri by adding your API keys. Embed the chat widget or connect via WebSocket. Your users chat with the AI agent directly in your app.

User wants to buy
Purchase Flow

Balance Check

Webhook to your app

Confirmed

Charge

Process payment

Paid

Order Created

Stored in Fauri

Notify

Fulfillment

Merchant ships

When a user decides to purchase, Fauri sends a balance_check webhook to your app. You confirm the balance, Fauri sends a charge webhook, you process payment. The order is created and the merchant is notified to fulfill it.

1

Merchants Onboard

Merchants connect their Shopify store via the merchant portal. Products auto-sync into Fauri's catalog.

2

You Integrate

Get API keys from the dashboard. Embed the chat widget or connect via WebSocket with your client ID and secret.

3

Users Shop

Your users chat with the AI agent in natural language. It searches products, gives personalized recommendations, and handles checkout.

4

Orders Fulfilled

Webhooks handle balance checks and charges. Orders are created automatically and merchants fulfill them.

Quick Start

Get up and running in 5 minutes

Follow these steps to connect your app to the Fauri AI shopping agent.

1

Create an account & get API keys

Sign up on the Portal to create your company account. You'll receive a Client ID, Secret Key, and Webhook Secret from your dashboard.

2

Register your users

Create users in Fauri so the agent can track their conversations and orders. Each user needs a unique ID from your system.

cURL
curl -X POST https://api.fauri.ai/api/v1/users/ \
  -H "X-Client-ID: your_client_id" \
  -H "X-Secret-Key: your_secret_key" \
  -H "Content-Type: application/json" \
  -d '{"external_user_id": "user_123", "display_name": "Alice"}'
3

Connect via WebSocket

Open a WebSocket connection for each user session. The AI agent handles the conversation, product search, and checkout flow automatically.

JavaScript
const ws = new WebSocket(
  "wss://api.fauri.ai/ws/agent/" +
  "?client_id=YOUR_ID&secret_key=YOUR_KEY&user_id=user_123"
);

ws.onopen = () => ws.send(JSON.stringify({
  message: "Show me running shoes under $150"
}));

ws.onmessage = (e) => {
  const data = JSON.parse(e.data);
  console.log(data.message);   // Agent's response text
  console.log(data.products);  // Product cards (if any)
};
4

Handle webhooks for payments

Set up a webhook endpoint on your server. When a user wants to buy something, Fauri sends a balance_check event, then a charge event. You respond with the user's balance and payment confirmation.

JavaScript
// Your server receives:
// POST /webhooks/fauri  { event: "balance_check", user_id, amount }
// → Respond: { "approved": true }

// POST /webhooks/fauri  { event: "charge", user_id, amount, token_address, token, network }
// → Respond: { "success": true, "transaction_id": "tx_abc123def" }
5

Done! Monitor via REST API

Use the REST endpoints to fetch chat history, list users, view orders, and manage addresses. The agent handles everything else — product discovery, recommendations, and the purchase conversation.

Authentication

API Key Authentication

All API requests must include your credentials via HTTP headers. You can find your Client ID and Secret Key on the Dashboard.

Base URLs

RESThttps://api.fauri.ai
WSwss://api.fauri.ai

Required Headers

X-Client-ID

Your unique client identifier (found on the Dashboard)

X-Secret-Key

Your secret API key (keep this private, never expose in client-side code)

HTTP
GET /api/v1/users/ HTTP/1.1
Host: api.fauri.ai
X-Client-ID: your_client_id
X-Secret-Key: your_secret_key
Content-Type: application/json

WebSocket Chat

WebSocket Endpoint

wss://api.fauri.ai/ws/agent/?client_id=...&secret_key=...&user_id=...

Open a persistent connection for each user session. The AI agent manages the full conversation — product discovery, recommendations, size/variant selection, and checkout — all through natural language. The connection stays open until the user leaves or you close it.

Connection Parameters

client_id

Your company's Client ID

Required — used for authentication

secret_key

Your company's Secret Key

Required — keep server-side only

user_id

Your app's unique identifier for this user

Required — must be pre-registered via REST API

Message Format

Send (Client → Server)

JSON
{ "message": "Find me running shoes under $150" }

Receive (Server → Client) — Text response

JSON
{
  "type": "agent_response",
  "message": "I found some great running shoes for you! Here are 3 options under $150..."
}

Receive (Server → Client) — With product results

JSON
{
  "type": "agent_response",
  "message": "Here are the running shoes I found:",
  "products": [
    {
      "id": "prod_abc123",
      "title": "Nike Air Zoom Pegasus 41",
      "description": "Lightweight neutral running shoe",
      "merchant": "FitGear Store",
      "image_url": "https://...",
      "variants": [
        {
          "id": "var_001",
          "title": "Black / Size 10",
          "price": "129.99",
          "available_qty": 15
        }
      ]
    }
  ]
}

Receive (Server → Client) — Order placed

JSON
{
  "type": "agent_response",
  "message": "Your order has been placed successfully!",
  "order": {
    "id": "ord_xyz789",
    "status": "PAID",
    "amount": "129.99",
    "items": [{ "product": "Nike Air Zoom Pegasus 41", "variant": "Black / Size 10", "qty": 1 }]
  }
}

Agent Capabilities

The AI agent uses these tools internally — you don't need to call them. Just send natural language messages.

search_products

Find products by query

get_product

View product details

register_user

Create user accounts

add_address

Save shipping info

get_addresses

List saved addresses

check_balance

Verify user funds

buy_product

Place an order

order_history

View past orders

REST Endpoints

These endpoints require X-Client-ID and X-Secret-Key headers for authentication.

POST/api/v1/users/

Create or register a new user for your company.

Register a user before they can connect via WebSocket. The external_user_id should be your app's unique identifier for this user.

Request body

JSON
{
  "external_user_id": "user_alice_123",
  "display_name": "Alice"
}

Response (201)

JSON
{
  "id": "usr_abc123",
  "external_user_id": "user_alice_123",
  "display_name": "Alice",
  "created_at": "2026-03-06T10:00:00Z"
}
GET/api/v1/users/

List all users associated with your company.

Returns a paginated list of users who have interacted with your integration of the Fauri agent.

Response (200)

JSON
{
  "count": 42,
  "next": "/api/v1/users/?page=2",
  "results": [
    {
      "id": "usr_abc123",
      "external_user_id": "user_alice_123",
      "display_name": "Alice",
      "created_at": "2026-03-06T10:00:00Z"
    }
  ]
}
GET/api/v1/chat/history/?user_id={user_id}

Retrieve the chat history for a specific user.

Returns all messages exchanged between the user and the AI agent, ordered chronologically. Useful for displaying past conversations or syncing state.

Response (200)

JSON
[
  {
    "role": "user",
    "content": "Show me running shoes under $150",
    "timestamp": "2026-03-06T10:05:00Z"
  },
  {
    "role": "assistant",
    "content": "I found 3 running shoes under $150...",
    "products": [...],
    "timestamp": "2026-03-06T10:05:03Z"
  }
]
GET/api/v1/users/{user_id}/orders/

Get all orders placed by a user.

Returns order history including status, line items, amounts, and fulfillment tracking.

Response (200)

JSON
[
  {
    "id": "ord_xyz789",
    "status": "PAID",
    "amount": "129.99",
    "currency": "USD",
    "items": [
      {
        "product_title": "Nike Air Zoom Pegasus 41",
        "variant_title": "Black / Size 10",
        "quantity": 1,
        "price": "129.99"
      }
    ],
    "shipping_address": {
      "line1": "123 Main St",
      "city": "New York",
      "state": "NY",
      "zip": "10001"
    },
    "created_at": "2026-03-06T10:10:00Z"
  }
]
GET/api/v1/users/{user_id}/addresses/

Get saved shipping addresses for a user.

Returns all shipping addresses on file. Users can save addresses through the AI agent conversation or you can add them via this endpoint.

Response (200)

JSON
[
  {
    "id": "addr_001",
    "label": "Home",
    "line1": "123 Main St",
    "line2": "Apt 4B",
    "city": "New York",
    "state": "NY",
    "zip": "10001",
    "country": "US"
  }
]

Webhooks

Signature Verification

All webhook requests include an X-Webhook-Signature header. Verify this signature using your Webhook Secret to ensure the request is authentic.

Webhook Events

POSTbalance_check

Sent when the AI agent needs to verify a user's balance before placing an order.

JSON
{
  "event": "balance_check",
  "user_id": "0x1234...abcd",
  "amount": "149.99",
  "currency": "USD",
  "order_id": "ord_abc123",
  "timestamp": "2026-03-04T12:00:00Z"
}
POSTcharge

Sent when a payment is processed for an order.

JSON
{
  "event": "charge",
  "user_id": "0x1234...abcd",
  "amount": "149.99",
  "currency": "USD",
  "order_id": "ord_abc123",
  "tx_hash": "0x8f3a...c721",
  "status": "completed",
  "timestamp": "2026-03-04T12:00:05Z"
}

Expected Response

Your webhook endpoint should respond with a JSON body indicating success:

JSON
// For balance_check — approve or decline the order
{
  "approved": true
}
// Or decline with a reason:
{
  "approved": false,
  "reason": "Insufficient balance"
}

// For charge — confirm the payment was processed
{
  "success": true,
  "transaction_id": "tx_abc123def"
}

// For order_followup — just acknowledge receipt
{
  "received": true
}

Errors & Status Codes

HTTP Status Codes

200OKRequest succeeded
201CreatedResource created successfully
400Bad RequestInvalid request body or parameters
401UnauthorizedMissing or invalid API keys
403ForbiddenValid keys but insufficient permissions
404Not FoundResource does not exist
429Rate LimitedToo many requests — slow down
500Server ErrorSomething went wrong on our end

Error Response Format

All error responses follow a consistent JSON structure:

JSON
{
  "error": "Invalid credentials",
  "detail": "The X-Client-ID or X-Secret-Key header is missing or invalid.",
  "status": 401
}

WebSocket Close Codes

1000Normal closure — conversation ended
4001Authentication failed — invalid credentials
4004User not found — register the user first
4029Rate limited — too many messages

Rate Limits

REST API: 100 requests/minute per API key. WebSocket: 30 messages/minute per connection. If you need higher limits, contact us.

JavaScript Examples

JavaScript
// Connect to the Fauri AI agent via WebSocket
const WS_URL = "wss://api.fauri.ai/ws/agent/";
const CLIENT_ID = "your_client_id";
const SECRET_KEY = "your_secret_key";
const USER_ID = "0x1234...abcd";

const ws = new WebSocket(
  `${WS_URL}?client_id=${CLIENT_ID}&secret_key=${SECRET_KEY}&user_id=${USER_ID}`
);

ws.onopen = () => {
  console.log("Connected to Fauri agent");
  ws.send(JSON.stringify({
    message: "Show me running shoes under $150"
  }));
};

ws.onmessage = (event) => {
  const data = JSON.parse(event.data);
  console.log("Agent response:", data.message);

  // Handle product results
  if (data.products) {
    data.products.forEach(p => {
      console.log(`  - ${p.name}: $${p.price}`);
    });
  }
};

ws.onerror = (error) => {
  console.error("WebSocket error:", error);
};

ws.onclose = () => {
  console.log("Disconnected from Fauri agent");
};
JavaScript
// Fetch chat history via REST API
const API_URL = "https://api.fauri.ai";
const CLIENT_ID = "your_client_id";
const SECRET_KEY = "your_secret_key";

async function getChatHistory(userId) {
  const res = await fetch(
    `${API_URL}/api/v1/chat/history/?user_id=${userId}`,
    {
      headers: {
        "X-Client-ID": CLIENT_ID,
        "X-Secret-Key": SECRET_KEY,
      },
    }
  );
  return await res.json();
}

// List all users
async function listUsers() {
  const res = await fetch(`${API_URL}/api/v1/users/`, {
    headers: {
      "X-Client-ID": CLIENT_ID,
      "X-Secret-Key": SECRET_KEY,
    },
  });
  return await res.json();
}
JavaScript
// Verify webhook signature (Node.js / Express)
const crypto = require("crypto");

function verifyWebhookSignature(body, timestamp, signature, secret) {
  // Signature is HMAC-SHA256 of "{timestamp}.{body}"
  const expected = "sha256=" + crypto
    .createHmac("sha256", secret)
    .update(`${timestamp}.${body}`)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(signature),
    Buffer.from(expected)
  );
}

app.post("/webhooks/kays", express.raw({ type: "application/json" }), (req, res) => {
  const signature = req.headers["x-webhook-signature"];
  const timestamp = req.headers["x-webhook-timestamp"];
  const body = req.body.toString();

  if (!verifyWebhookSignature(body, timestamp, signature, process.env.KAYS_WEBHOOK_SECRET)) {
    return res.status(401).json({ error: "Invalid signature" });
  }

  const payload = JSON.parse(body);
  const { type, user_id, amount, order_id } = payload;

  if (type === "balance_check") {
    const canAfford = checkUserBalance(user_id, amount);
    return res.json({ approved: canAfford });
  }

  if (type === "charge") {
    const txId = processCharge(user_id, amount, order_id);
    return res.json({ success: true, transaction_id: txId });
  }

  res.json({ success: true });
});

Python Examples

Python
# Connect to the Fauri AI agent via WebSocket
import asyncio
import json
import websockets

CLIENT_ID = "your_client_id"
SECRET_KEY = "your_secret_key"
USER_ID = "0x1234...abcd"

async def chat_with_agent():
    uri = (
        f"wss://api.fauri.ai/ws/agent/"
        f"?client_id={CLIENT_ID}"
        f"&secret_key={SECRET_KEY}"
        f"&user_id={USER_ID}"
    )

    async with websockets.connect(uri) as ws:
        # Send a message
        await ws.send(json.dumps({
            "message": "Show me running shoes under $150"
        }))

        # Receive response
        response = await ws.recv()
        data = json.loads(response)
        print(f"Agent: {data['message']}")

        if "products" in data:
            for p in data["products"]:
                print(f"  - {p['name']}: ${p['price']}")

asyncio.run(chat_with_agent())
Python
# REST API usage with requests
import requests

API_URL = "https://api.fauri.ai"
HEADERS = {
    "X-Client-ID": "your_client_id",
    "X-Secret-Key": "your_secret_key",
}

# List all users
def list_users():
    r = requests.get(f"{API_URL}/api/v1/users/", headers=HEADERS)
    return r.json()

# Get chat history for a user
def get_chat_history(user_id: str):
    r = requests.get(
        f"{API_URL}/api/v1/chat/history/?user_id={user_id}",
        headers=HEADERS,
    )
    return r.json()

# Get user orders
def get_user_orders(user_id: str):
    r = requests.get(
        f"{API_URL}/api/v1/users/{user_id}/orders/",
        headers=HEADERS,
    )
    return r.json()

# Create a new user
def create_user(user_id: str, display_name: str = ""):
    r = requests.post(
        f"{API_URL}/api/v1/users/",
        headers={**HEADERS, "Content-Type": "application/json"},
        json={"external_user_id": user_id, "display_name": display_name},
    )
    return r.json()
Python
# Verify webhook signature (Flask)
import hmac
import hashlib
from flask import Flask, request, jsonify

app = Flask(__name__)
WEBHOOK_SECRET = "your_webhook_secret"

def verify_signature(body: bytes, timestamp: str, signature: str) -> bool:
    # Signature is HMAC-SHA256 of "{timestamp}.{body}"
    expected = "sha256=" + hmac.new(
        WEBHOOK_SECRET.encode(),
        f"{timestamp}.{body.decode()}".encode(),
        hashlib.sha256,
    ).hexdigest()
    return hmac.compare_digest(signature, expected)

@app.route("/webhooks/kays", methods=["POST"])
def handle_webhook():
    signature = request.headers.get("X-Webhook-Signature", "")
    timestamp = request.headers.get("X-Webhook-Timestamp", "")
    body = request.get_data()

    if not verify_signature(body, timestamp, signature):
        return jsonify({"error": "Invalid signature"}), 401

    payload = request.json
    event_type = payload["type"]
    user_id = payload["user_id"]
    amount = payload["amount"]

    if event_type == "balance_check":
        can_afford = check_user_balance(user_id, amount)
        return jsonify({"approved": can_afford})

    if event_type == "charge":
        tx_id = process_charge(user_id, amount)
        return jsonify({"success": True, "transaction_id": tx_id})

    return jsonify({"success": True})