Vaizent Documentation

Welcome to the Vaizent AI platform documentation. This guide covers everything from creating your first agent to integrating the REST API.

Quick Start

Get from zero to a live AI agent in 5 steps:

  1. Create a free account at /auth/signup
  2. Go to Agents → New Agent in your dashboard
  3. Follow the wizard: name, tone, system prompt
  4. Add training content (text, PDF, URL, or FAQ)
  5. Copy the embed script and paste it on your website
Note: Your agent starts in Draft status. Change it to Active before embedding - Draft agents do not respond to visitors.

Agents

Creating an Agent

Navigate to Dashboard → Agents → New Agent. The multi-step wizard guides you through:

  • Template selection (10 pre-built templates)
  • Basic info: name, description, welcome message
  • Personality: tone preset, behaviour tags, system prompt
  • Knowledge Base: add training content
  • Widget: theme, icon, colour, position, voice AI

System Prompts

The system prompt is the master instruction set the AI receives before every conversation. A good system prompt includes:

You are [Name], an AI assistant for [Company].
You answer questions about [topics].
Tone: friendly and concise.
If you don't know the answer, say: "I'm not sure - please contact our support team at support@company.com."
Never discuss competitor products.

Click Generate with AI to have the platform write a system prompt based on your agent name, description, and selected tone.

Tone & Language

Available tones: Friendly, Formal, Professional, Casual, Technical, Salesy, Supportive, Funny

Language: set the primary response language. The agent will respond in this language regardless of the visitor's input language.

Knowledge Base

Text Training

Paste any text content directly into the training interface. All plans supported. Best for: company info, product descriptions, policies.

PDF Upload

Upload PDF files. Size limits: Basic (10 MB), Pro (25 MB), Pro Plus (100 MB). Text-based PDFs only - scanned image PDFs may have limited accuracy.

URL Scraping

Enter any public URL. The platform renders it with a headless browser and extracts text content. Page limits: Basic (10), Pro (50), Pro Plus (500).

Note: Scraping only works on publicly accessible pages. Password-protected or login-gated content cannot be scraped - use text paste or PDF upload instead.

FAQ Builder

Create explicit question-and-answer pairs. FAQs are matched with high priority. Write questions exactly as customers would ask them.

Widget & Embed

Basic Embed

Add this script tag to any HTML page:

<script
    src="https://vaizent.com/widget.js"
    data-agent-id="YOUR_AGENT_ID"
    async >
</script>

Find your agent ID on the Embed tab of the agent detail page.

WordPress

Download the Vaizent WordPress plugin from the Embed tab, or add the script via the Insert Headers and Footers plugin in your WordPress admin.

Next.js

import Script from 'next/script';

// In layout.js or a specific page
<Script
  src="https://vaizent.com/widget.js"
  data-agent-id="YOUR_AGENT_ID"
  strategy="lazyOnload"
/>

Shopify

Go to Online Store → Themes → Edit code → layout/theme.liquid. Paste the script just before </body>.

Lead Capture

Setting Up Leads

Enable Collect Leads in the agent wizard (Widget step). Choose which fields to collect: Name, Email, Phone. Requires Basic plan or above.

Viewing Leads

Go to Dashboard → Leads. Search, filter, view AI summaries, and export all leads as CSV.

Webhooks

Available events:

  • new_conversation - a new chat session started
  • lead_captured - visitor submitted the lead form
  • message_sent - agent responded to a message

Configure webhooks at Agent → Integrations → Webhooks. Requires Pro plan or above.

All payloads are signed with HMAC-SHA256. Verify the X-Vaizent-Signature header on your server.

WhatsApp Integration

Requires Pro Plus plan.

  1. Go to Agent → Integrations → Connect WhatsApp
  2. Scan the QR code with WhatsApp on your phone
  3. The session is established and persisted server-side
  4. Incoming messages are now handled by the AI agent automatically
Lead Forwarding: Every new lead captured on your website can be sent as a WhatsApp notification to your connected number instantly.

API Reference

Overview

The Vaizent Developer API lets you build completely custom chat UIs while using your agent's knowledge base, system prompt, tone, and settings under the hood - identical to how the hosted widget works.

Every request uses your Agent ID + a per-agent API Key. Both are found on your agent's Integrations → API Access tab.

Plan requirement: Developer API access requires the Pro plan or above. The API Access tab will prompt you to upgrade if needed.

Authentication

Every request requires two credentials:

  • Authorization header - Bearer vai_your_api_key_here
  • agentId field in the request body
Headers
Authorization: Bearer vai_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Content-Type: application/json

Your API key is scoped to a single agent. Each agent has its own key. You can rotate or disable keys at any time from the dashboard.

Chat Endpoint

POST https://vaizent.com/api/v1/chat

Send a message to your agent. The agent uses its full knowledge base (RAG), system prompt, and conversation history to reply.

Request Body

JSON
{
  "agentId":   "vaizent_yourname_12345",   // required - your Agent ID
  "message":   "What are your pricing plans?",  // required - user message
  "sessionId": "user-abc-session-001",     // optional - for multi-turn memory
  "history": [                             // optional - previous turns
    { "role": "user",      "content": "Hi" },
    { "role": "assistant", "content": "Hello! How can I help?" }
  ]
}
FieldTypeRequiredDescription
agentIdstring✅ YesYour agent's ID (shown on Integrations → API Access)
messagestring✅ YesThe user's message (max ~4000 chars)
sessionIdstringNoConversation session key. Auto-generated on first call if omitted; pass it back on subsequent calls for memory.
historyarrayNoArray of { role, content } objects. Up to 50 entries.

Response Format

200 OK
{
  "reply":     "Our Pro plan is $29/mo and includes...",
  "sessionId": "user-abc-session-001",
  "agentId":   "vaizent_yourname_12345",
  "latencyMs": 420,
  "ragChunks": 4
}
FieldDescription
replyThe agent's response text (markdown supported)
sessionIdUse this in the next request to maintain conversation memory
agentIdConfirms which agent replied
latencyMsTotal LLM round-trip time in milliseconds
ragChunksNumber of knowledge base chunks used to answer

Error Codes

HTTPCodeMeaning
400agentId requiredMissing agentId in request body
400message requiredMissing message in request body
401Missing API keyNo Authorization header sent
403Invalid API keyKey doesn't match agent, or key is disabled
404Agent not foundThe agentId doesn't exist
429Rate limit exceededToo many requests - slow down or upgrade plan
500Failed to processInternal error - retry after a moment

Next.js Integration - Full Setup Guide

This guide shows how to build a custom AI chat widget in a Next.js App Router project using the Vaizent API.

Step 1 - Store credentials in environment variables

Create or update your .env.local:

.env.local
VAIZENT_AGENT_ID=vaizent_yourname_12345
VAIZENT_API_KEY=vai_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Security: Never expose VAIZENT_API_KEY to the browser. Always proxy through a Next.js API route.

Step 2 - Create a proxy API route

Create app/api/chat/route.js in your project:

app/api/chat/route.js
export async function POST(request) {
  const { message, sessionId, history } = await request.json();

  if (!message?.trim()) {
    return Response.json({ error: 'message is required' }, { status: 400 });
  }

  const res = await fetch('https://vaizent.com/api/v1/chat', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${process.env.VAIZENT_API_KEY}`,
    },
    body: JSON.stringify({
      agentId:   process.env.VAIZENT_AGENT_ID,
      message,
      sessionId,
      history,
    }),
  });

  const data = await res.json();
  return Response.json(data, { status: res.status });
}

Step 3 - Build the chat component

Create components/AiChat.jsx:

components/AiChat.jsx
'use client';

import { useState, useRef, useEffect } from 'react';

export default function AiChat() {
  const [messages,  setMessages]  = useState([]);
  const [input,     setInput]     = useState('');
  const [loading,   setLoading]   = useState(false);
  const [sessionId, setSessionId] = useState('');
  const bottomRef = useRef(null);

  useEffect(() => {
    bottomRef.current?.scrollIntoView({ behavior: 'smooth' });
  }, [messages, loading]);

  async function send(e) {
    e.preventDefault();
    const text = input.trim();
    if (!text || loading) return;

    const history = messages.map(m => ({ role: m.role, content: m.content }));
    setMessages(prev => [...prev, { role: 'user', content: text }]);
    setInput('');
    setLoading(true);

    try {
      const res = await fetch('/api/chat', {
        method:  'POST',
        headers: { 'Content-Type': 'application/json' },
        body:    JSON.stringify({ message: text, sessionId, history }),
      });
      const data = await res.json();

      if (!res.ok) throw new Error(data.error || 'Request failed');
      if (data.sessionId) setSessionId(data.sessionId);
      setMessages(prev => [...prev, { role: 'assistant', content: data.reply }]);
    } catch (err) {
      setMessages(prev => [...prev, { role: 'error', content: err.message }]);
    } finally {
      setLoading(false);
    }
  }

  return (
    <div style={{ display: 'flex', flexDirection: 'column', height: 480,
                  border: '1px solid #e5e7eb', borderRadius: 12, overflow: 'hidden' }}>
      {/* Messages */}
      <div style={{ flex: 1, overflowY: 'auto', padding: 16, display: 'flex',
                    flexDirection: 'column', gap: 8 }}>
        {messages.length === 0 && (
          <p style={{ color: '#9ca3af', textAlign: 'center', marginTop: 40 }}>
            Ask me anything…
          </p>
        )}
        {messages.map((m, i) => (
          <div key={i} style={{
            alignSelf: m.role === 'user' ? 'flex-end' : 'flex-start',
            background: m.role === 'user' ? '#6366f1' : '#f3f4f6',
            color:      m.role === 'user' ? '#fff'    : '#111',
            padding: '8px 14px', borderRadius: 18, maxWidth: '80%',
            fontSize: 14, lineHeight: 1.5,
          }}>
            {m.content}
          </div>
        ))}
        {loading && (
          <div style={{ alignSelf: 'flex-start', background: '#f3f4f6',
                        padding: '8px 14px', borderRadius: 18, fontSize: 14 }}>
            <span>…</span>
          </div>
        )}
        <div ref={bottomRef} />
      </div>

      {/* Input */}
      <form onSubmit={send} style={{ display: 'flex', borderTop: '1px solid #e5e7eb' }}>
        <input
          value={input}
          onChange={e => setInput(e.target.value)}
          placeholder="Type a message…"
          disabled={loading}
          style={{ flex: 1, padding: '12px 16px', border: 'none',
                   outline: 'none', fontSize: 14 }}
        />
        <button type="submit" disabled={loading || !input.trim()}
          style={{ padding: '12px 20px', background: '#6366f1', color: '#fff',
                   border: 'none', cursor: 'pointer', fontWeight: 600 }}>
          Send
        </button>
      </form>
    </div>
  );
}

Step 4 - Use it anywhere

app/support/page.jsx
import AiChat from '@/components/AiChat';

export default function SupportPage() {
  return (
    <main>
      <h1>Support</h1>
      <AiChat />
    </main>
  );
}

React (Vite / CRA) Integration

For non-Next.js React apps, never call the Vaizent API directly from the browser - proxy via your own backend to protect your API key.

Express.js proxy endpoint

server.js (Express)
import express from 'express';
const app = express();
app.use(express.json());

app.post('/api/chat', async (req, res) => {
  const { message, sessionId, history } = req.body;

  const upstream = await fetch('https://vaizent.com/api/v1/chat', {
    method:  'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${process.env.VAIZENT_API_KEY}`,
    },
    body: JSON.stringify({
      agentId:   process.env.VAIZENT_AGENT_ID,
      message,
      sessionId,
      history,
    }),
  });

  const data = await upstream.json();
  res.status(upstream.status).json(data);
});

app.listen(3001);

React hook - useVaizentChat

hooks/useVaizentChat.js
import { useState, useCallback } from 'react';

export function useVaizentChat() {
  const [messages,  setMessages]  = useState([]);
  const [loading,   setLoading]   = useState(false);
  const [sessionId, setSessionId] = useState('');

  const send = useCallback(async (text) => {
    if (!text.trim() || loading) return;

    const history = messages.map(m => ({ role: m.role, content: m.content }));
    setMessages(prev => [...prev, { role: 'user', content: text }]);
    setLoading(true);

    try {
      const res = await fetch('/api/chat', {
        method:  'POST',
        headers: { 'Content-Type': 'application/json' },
        body:    JSON.stringify({ message: text, sessionId, history }),
      });
      const data = await res.json();

      if (!res.ok) throw new Error(data.error || 'Error');
      if (data.sessionId) setSessionId(data.sessionId);
      setMessages(prev => [...prev, { role: 'assistant', content: data.reply }]);
    } catch (err) {
      setMessages(prev => [...prev, { role: 'error', content: err.message }]);
    } finally {
      setLoading(false);
    }
  }, [messages, sessionId, loading]);

  return { messages, loading, send };
}
ChatWidget.jsx
import { useState } from 'react';
import { useVaizentChat } from '../hooks/useVaizentChat';

export default function ChatWidget() {
  const [input, setInput] = useState('');
  const { messages, loading, send } = useVaizentChat();

  const handleSubmit = (e) => {
    e.preventDefault();
    send(input);
    setInput('');
  };

  return (
    <div className="chat-widget">
      <div className="chat-messages">
        {messages.map((m, i) => (
          <div key={i} className={`msg msg-${m.role}`}>
            {m.content}
          </div>
        ))}
        {loading && <div className="msg msg-assistant">…</div>}
      </div>
      <form onSubmit={handleSubmit}>
        <input
          value={input}
          onChange={e => setInput(e.target.value)}
          placeholder="Ask something…"
          disabled={loading}
        />
        <button type="submit" disabled={loading || !input.trim()}>Send</button>
      </form>
    </div>
  );
}

Rate Limits & Security

  • Rate limit: 60 requests/minute per API key. Exceeding this returns HTTP 429.
  • Key security: Your API key is secret - never include it in client-side code, public repos, or browser bundles. Always proxy via a server-side route.
  • Key rotation: Use the Rotate button on the API Access tab if you suspect a key has been leaked. The old key stops working instantly.
  • Key disabling: Toggle the key off at any time without deleting it. Re-enable when ready.
  • Per-agent scope: Each API key grants access to exactly one agent. A key from Agent A cannot query Agent B.
  • History limit: The history array accepts up to 50 messages. Excess entries are dropped.
  • Response data: Only the reply string is needed for basic usage; ragChunks is useful for debugging why an answer was given.