Vexar Chat

Data API Documentation

Connect your website's product catalog, services, orders, and customer accounts to the Vexar.Chat AI chatbot.

1. Overview

Data API allows the Vexar.Chat AI chatbot to query your website's data in real time. When a visitor asks about products, services, stock availability, order status, or account information, the chatbot calls your API endpoint and uses the response to provide accurate, up-to-date answers.

How it works:
  1. Visitor asks: "Do you have red sneakers under $50?"
  2. AI decides to call search_products with {"query": "red sneakers", "max_price": 50}
  3. Your API endpoint receives the request and returns matching products from your database
  4. AI formats the results into a natural language response for the visitor

2. Quick Start

  1. Create a single API endpoint on your website (e.g., https://your-site.com/vexar-api/)
  2. The endpoint should accept POST requests with JSON body
  3. Implement handlers for the actions your chatbot needs (at minimum: ping)
  4. In Vexar.Chat dashboard → Chatbot Settings → Data API: enable, enter your URL and API key
  5. Click "Test connection" to verify everything works

3. Request Format

The chatbot sends a POST request to your URL with the following JSON body:

{
    "action": "search_products",
    "params": {
        "query": "red sneakers",
        "max_price": 50,
        "in_stock": true
    }
}

Headers:

HeaderValue
Content-Typeapplication/json
AuthorizationBearer YOUR_API_KEY
User-AgentVexarChat-DataAPI/1.0

4. Response Format

Successful response:

{
    "success": true,
    "data": [
        {
            "id": 123,
            "name": "Nike Air Max Red",
            "price": 45.99,
            "currency": "USD",
            "url": "https://your-site.com/product/nike-air-max-red",
            "in_stock": true,
            "image": "https://your-site.com/images/nike-air-max-red.jpg"
        }
    ]
}

Error response:

{
    "success": false,
    "error": "Product not found"
}

5. Actions Reference

ping

Health check. Used by "Test connection" button in dashboard.

ParamsResponse
None{"success": true, "data": {"status": "ok"}}

search_products

Search for products or services by keyword, category, price range, and availability.

ParamTypeRequiredDescription
querystringNoSearch keywords
categorystringNoCategory name or ID
min_pricenumberNoMinimum price
max_pricenumberNoMaximum price
in_stockbooleanNoOnly in-stock items
limitintegerNoMax results (default 5, max 10)

Expected response data: array of products, each with: id, name, price, currency, url, in_stock, image (optional), description (optional)

get_product

Get detailed information about a specific product or service by its ID.

ParamTypeRequiredDescription
product_idstringYesProduct or service ID

Expected response data: single product object with all details: id, name, price, currency, url, in_stock, description, specifications, images

get_categories

Get the list of available categories.

ParamsResponse
NoneArray of {"id", "name", "count"}

check_availability

Check stock availability or service booking slots.

ParamTypeRequiredDescription
product_idstringYesProduct or service ID

Expected response: {"in_stock": true, "quantity": 15} or for services: {"available": true, "next_slot": "2026-03-15 10:00"}

check_order_status

Check order status by order ID or customer email.

ParamTypeRequiredDescription
order_idstringNo*Order number
emailstringNo*Customer email

* At least one of order_id or email is required.
Expected response data: {"order_id", "status", "created_at", "total", "items": [...]}

lookup_account

Look up customer account or subscription information by account ID, phone, email, or contract number. Ideal for ISPs, telecom, utilities, SaaS, and any service with subscriber accounts.

ParamTypeRequiredDescription
account_idstringNo*Account / subscriber ID
phonestringNo*Customer phone number
emailstringNo*Customer email
contract_numberstringNo*Contract / agreement number

* At least one identifier should be provided. The response data structure is flexible — return any fields relevant to your business.

The AI will interpret any fields you return (balance, plan name, expiration date, usage stats, etc.) and present them naturally to the visitor.

Example response:

{
    "success": true,
    "data": {
        "account_id": "ACC-1001",
        "name": "John Smith",
        "tariff": "Pro 100 Mbps",
        "status": "active",
        "balance": 15.50,
        "currency": "USD",
        "next_billing": "2026-04-01",
        "expires_at": "2027-03-15"
    }
}

6. Code Examples

PHP (Universal)

<?php
// File: vexar-api/index.php
// This is a minimal example. Adapt the database queries to your CMS.

header('Content-Type: application/json');

// Verify API key
$authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? '';
$apiKey = str_replace('Bearer ', '', $authHeader);
if ($apiKey !== 'YOUR_SECRET_KEY') {
    http_response_code(401);
    echo json_encode(['success' => false, 'error' => 'Unauthorized']);
    exit;
}

// Parse request
$input = json_decode(file_get_contents('php://input'), true);
$action = $input['action'] ?? '';
$params = $input['params'] ?? [];

// Connect to your database
$pdo = new PDO('mysql:host=localhost;dbname=your_db', 'user', 'pass');

switch ($action) {
    case 'ping':
        echo json_encode(['success' => true, 'data' => ['status' => 'ok']]);
        break;

    case 'search_products':
        $query = $params['query'] ?? '';
        $maxPrice = $params['max_price'] ?? 999999;
        $limit = min(10, $params['limit'] ?? 5);

        $stmt = $pdo->prepare(
            "SELECT id, name, price, 'USD' as currency, url, (stock > 0) as in_stock
             FROM products
             WHERE name LIKE :q AND price <= :mp
             ORDER BY name LIMIT :lim"
        );
        $stmt->execute([':q' => "%{$query}%", ':mp' => $maxPrice, ':lim' => $limit]);
        echo json_encode(['success' => true, 'data' => $stmt->fetchAll(PDO::FETCH_ASSOC)]);
        break;

    case 'get_product':
        $id = $params['product_id'] ?? 0;
        $stmt = $pdo->prepare("SELECT * FROM products WHERE id = ?");
        $stmt->execute([$id]);
        $product = $stmt->fetch(PDO::FETCH_ASSOC);
        echo json_encode($product
            ? ['success' => true, 'data' => $product]
            : ['success' => false, 'error' => 'Product not found']
        );
        break;

    case 'get_categories':
        $stmt = $pdo->query("SELECT id, name, (SELECT COUNT(*) FROM products WHERE category_id = c.id) as count FROM categories c ORDER BY name");
        echo json_encode(['success' => true, 'data' => $stmt->fetchAll(PDO::FETCH_ASSOC)]);
        break;

    case 'check_availability':
        $id = $params['product_id'] ?? 0;
        $stmt = $pdo->prepare("SELECT stock FROM products WHERE id = ?");
        $stmt->execute([$id]);
        $row = $stmt->fetch(PDO::FETCH_ASSOC);
        echo json_encode($row
            ? ['success' => true, 'data' => ['in_stock' => $row['stock'] > 0, 'quantity' => (int)$row['stock']]]
            : ['success' => false, 'error' => 'Product not found']
        );
        break;

    case 'check_order_status':
        $orderId = $params['order_id'] ?? '';
        $email = $params['email'] ?? '';
        if ($orderId) {
            $stmt = $pdo->prepare("SELECT * FROM orders WHERE id = ?");
            $stmt->execute([$orderId]);
        } elseif ($email) {
            $stmt = $pdo->prepare("SELECT * FROM orders WHERE email = ? ORDER BY created_at DESC LIMIT 1");
            $stmt->execute([$email]);
        }
        $order = $stmt->fetch(PDO::FETCH_ASSOC) ?? null;
        echo json_encode($order
            ? ['success' => true, 'data' => $order]
            : ['success' => false, 'error' => 'Order not found']
        );
        break;

    case 'lookup_account':
        $accountId = $params['account_id'] ?? '';
        $phone = $params['phone'] ?? '';
        $email = $params['email'] ?? '';

        if ($accountId) {
            $stmt = $pdo->prepare("SELECT * FROM customers WHERE account_id = ?");
            $stmt->execute([$accountId]);
        } elseif ($phone) {
            $stmt = $pdo->prepare("SELECT * FROM customers WHERE phone = ?");
            $stmt->execute([$phone]);
        } elseif ($email) {
            $stmt = $pdo->prepare("SELECT * FROM customers WHERE email = ?");
            $stmt->execute([$email]);
        }
        $account = $stmt->fetch(PDO::FETCH_ASSOC) ?? null;
        echo json_encode($account
            ? ['success' => true, 'data' => $account]
            : ['success' => false, 'error' => 'Account not found']
        );
        break;

    default:
        echo json_encode(['success' => false, 'error' => "Unknown action: {$action}"]);
}

WordPress / WooCommerce

// Add to your theme's functions.php or create a custom plugin

add_action('rest_api_init', function() {
    register_rest_route('vexar/v1', '/data-api', [
        'methods'  => 'POST',
        'callback' => 'vexar_data_api_handler',
        'permission_callback' => 'vexar_verify_api_key',
    ]);
});

function vexar_verify_api_key($request) {
    $auth = $request->get_header('Authorization');
    return $auth === 'Bearer YOUR_SECRET_KEY';
}

function vexar_data_api_handler($request) {
    $action = $request['action'] ?? '';
    $params = $request['params'] ?? [];

    switch ($action) {
        case 'ping':
            return ['success' => true, 'data' => ['status' => 'ok']];

        case 'search_products':
            $args = [
                'post_type'   => 'product',
                's'           => $params['query'] ?? '',
                'posts_per_page' => min(10, $params['limit'] ?? 5),
                'post_status' => 'publish',
            ];
            $products = [];
            foreach (wc_get_products($args) as $p) {
                if (isset($params['max_price']) && $p->get_price() > $params['max_price']) continue;
                $products[] = [
                    'id'       => $p->get_id(),
                    'name'     => $p->get_name(),
                    'price'    => (float)$p->get_price(),
                    'currency' => get_woocommerce_currency(),
                    'url'      => $p->get_permalink(),
                    'in_stock' => $p->is_in_stock(),
                ];
            }
            return ['success' => true, 'data' => $products];

        // Add more cases as needed...

        default:
            return ['success' => false, 'error' => "Unknown action"];
    }
}
// API URL for Vexar.Chat: https://your-site.com/wp-json/vexar/v1/data-api

Node.js (Express)

const express = require('express');
const app = express();
app.use(express.json());

// Auth middleware
const verifyKey = (req, res, next) => {
    const auth = req.headers.authorization || '';
    if (auth !== 'Bearer YOUR_SECRET_KEY') return res.status(401).json({ success: false, error: 'Unauthorized' });
    next();
};

app.post('/vexar-api', verifyKey, async (req, res) => {
    const { action, params = {} } = req.body;

    switch (action) {
        case 'ping':
            return res.json({ success: true, data: { status: 'ok' } });

        case 'search_products':
            // Replace with your DB query
            const products = await db.query(`SELECT * FROM products WHERE name ILIKE $1 LIMIT $2`,
                [`%${params.query || ''}%`, params.limit || 5]);
            return res.json({ success: true, data: products.rows });

        case 'lookup_account':
            const id = params.account_id || params.phone || params.email || '';
            const account = await db.query(
                `SELECT * FROM customers WHERE account_id = $1 OR phone = $1 OR email = $1 LIMIT 1`, [id]);
            return res.json(account.rows[0]
                ? { success: true, data: account.rows[0] }
                : { success: false, error: 'Account not found' });

        default:
            return res.json({ success: false, error: `Unknown action: ${action}` });
    }
});

app.listen(3000);

7. Rules & Limits

RuleValue
Max items per response10 items
Default timeout5 seconds
Max timeout30 seconds
Response formatJSON only
HTTP methodPOST only
Max tool iterations per message3 (AI can call your API up to 3 times per visitor message)
Supported AI providersOpenAI, Anthropic (Claude), Google Gemini
Not supportedDeepSeek (no function calling support)
Important:
  • Your API must respond within the configured timeout (default 5 sec). Slow responses will be treated as errors.
  • Always implement the ping action for connection testing.
  • Return proper error messages in the error field — the AI will use them to inform the visitor.
  • Keep your API key secret. Rotate it regularly.

Need help implementing the API?

Contact Support