RestroAgent
AI-powered restaurant management SaaS — voice agent, chat widget, orders, bookings, menus, billing and more, all in one platform.
Introduction
RestroAgent is a full-stack SaaS platform that brings intelligent AI automation to restaurant businesses. At its core it provides a conversational AI agent that can answer phone calls, take orders, confirm table reservations and handle customer questions — completely autonomously, 24 hours a day, 7 days a week.
Restaurant owners and managers get a powerful web dashboard where every aspect of the business is managed in one place: live order tracking, booking timelines, menu builder, customer profiles, staff access control, performance analytics, billing and much more. Platform owners (SaaS operators) get a dedicated super-admin panel to manage all tenants, subscriptions, AI provider configuration, translations, and branding from a single interface.
Who is it for?
Restaurant Owners
Independent restaurants and chains that want to automate phone orders, reservations and customer service without hiring extra staff.
SaaS Operators
Developers and agencies who want to sell a white-label AI restaurant platform to multiple restaurant clients under their own brand.
Developers
Teams who need a production-ready, extensible Next.js + PostgreSQL codebase to build custom restaurant automation solutions on top of.
Core capabilities at a glance
AI Voice Agent
Real-time Twilio voice calls handled by an OpenAI-powered speech agent.
Embeddable Chat Widget
Drop a script tag on any website for instant AI chat support.
Order Management
Real-time order tracking with multi-status workflow and channel filtering.
Table Booking
Timeline view, VIP tagging, reminder automation, walk-in management.
Menu Builder
Categories, items, modifier groups, pricing and availability toggles.
Customer CRM
Unified profiles with order history, booking records and AI interactions.
Knowledge Base
Per-restaurant FAQs, policies and documents fed to the AI agent.
Multi-Branch
Each restaurant can operate multiple branches with isolated agents.
Subscription Billing
Stripe-powered plans with monthly/annual cycles, invoices and portal.
Multi-Language
Admin-managed translation system for the dashboard UI.
REST API & Webhooks
Outbound webhooks and API keys for external integrations.
Analytics
Revenue, conversation, and platform-wide usage dashboards.
Omnichannel Conversations
Unified inbox for chat, voice, WhatsApp, email and SMS with human takeover.
WhatsApp Integration
Connect Meta WhatsApp Business API for inbound/outbound messaging and campaigns.
QR Storefront
Mobile-first public ordering at /r/[restaurantSlug]/[branchSlug] — scan, browse, order, pay.
Table Management
Per-branch tables with unique QR codes and printable sheet generation.
Loyalty Program
Tiered point-based loyalty system with storefront checkout integration.
Gift Cards
Issue, distribute and redeem gift cards with a full balance ledger.
Coupons & Discounts
Flat, percentage and free-item coupons with usage limits and expiry.
Marketing Campaigns
Audience segments and broadcast campaigns via email and WhatsApp.
Multi-Language Support
AI-powered bulk translation, RTL auto-layout, per-user language selector and storefront localisation.
Platform Email System
SMTP setup, customisable transactional email templates and delivery log.
Help Desk
Support ticket system for restaurant owners with admin response threading.
Menu Bulk Upload
Import or update categories and items from a CSV file in one step.
Platform Branding
White-label setup: custom logo, brand colour, platform name and dynamic favicon.
Razorpay Billing
Alternative payment gateway for markets where Stripe is unavailable.
License
RestroAgent is distributed under the Envato Regular License (single end product for own use) or Extended License (end product to use SaaS). Refer to your CodeCanyon purchase receipt for the exact license terms. You may not redistribute or resell the source code itself.
Technology Stack
| Layer | Technology | Version |
|---|---|---|
| Framework | Next.js (App Router, Server Components) | 15 |
| Language | TypeScript | 5 |
| Styling | Tailwind CSS | 3 |
| Database | PostgreSQL | 15+ |
| ORM | Drizzle ORM (drizzle-orm) with pg driver |
0.45 |
| Auth | JWT (jose) stored in HttpOnly cookies |
— |
| AI — Chat | OpenAI Agents SDK, OpenRouter | — |
| AI — Voice | OpenAI Realtime API via Twilio Media Streams (WebSocket) | — |
| TTS | OpenAI Realtime API (voice synthesis handled natively during calls) | — |
| Telephony | Twilio | — |
| Payments | Stripe Subscriptions + Billing Portal | — |
| Nodemailer — any SMTP provider | — | |
| Runtime | Node.js via tsx custom server |
20+ |
| Process Manager | PM2 (recommended for VPS deployment) | — |
| Web Server | Nginx (reverse proxy, recommended) | — |
System Requirements
Minimum server specifications (VPS)
| Resource | Minimum | Recommended |
|---|---|---|
| CPU | 1 vCPU | 2 vCPU |
| RAM | 1 GB | 2–4 GB |
| Disk | 20 GB SSD | 40 GB SSD |
| OS | Ubuntu 22.04 LTS | Ubuntu 22.04 / 24.04 LTS |
| Node.js | 20.x | 22.x LTS |
| PostgreSQL | 15 | 16 |
| npm | 10+ | 10+ |
External service accounts required
- OpenAI — platform.openai.com — for chat and voice AI (required)
- Twilio — twilio.com — for inbound/outbound voice calls (required for voice features)
- Stripe — stripe.com — for subscription billing (required for billing features)
- SMTP provider — SendGrid, Mailgun, Amazon SES, or any transactional email service (required for email notifications)
- OpenRouter — optional; enables additional LLM models per agent (including Claude, Gemini, and other providers via the OpenRouter gateway)
- ElevenLabs — coming soon; will enable premium TTS voice synthesis
- Deepgram — coming soon; will enable Deepgram Aura TTS voice synthesis
- Sarvam AI — coming soon; will enable Indian-language TTS voices (Hindi, Tamil, Telugu, and more)
Installation Guide — Live Server / VPS
The steps below assume a fresh Ubuntu 22.04 LTS server. Commands marked
with # are run as root; commands without are run as your application user.
Step 1 — Prepare the Server
Update the system and install essential build tools.
$ sudo apt update && sudo apt upgrade -y $ sudo apt install -y curl wget git build-essential unzip ufw
Configure the firewall to allow SSH, HTTP and HTTPS.
$ sudo ufw allow OpenSSH $ sudo ufw allow 80/tcp $ sudo ufw allow 443/tcp $ sudo ufw enable
Create a dedicated application user (recommended — avoids running as root).
$ sudo adduser restroagent $ sudo usermod -aG sudo restroagent $ su - restroagent
Step 2 — Install Node.js 20 via nvm
Install nvm (Node Version Manager) — the recommended approach for VPS deployments. nvm lets you install multiple Node.js versions and switch between them without touching system packages.
$ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash $ source ~/.bashrc # load nvm into the current shell
Install Node.js 20 LTS and set it as the default.
$ nvm install 20 $ nvm use 20 $ nvm alias default 20
Verify the installation.
$ node -v # should output v20.x.x $ npm -v # should output 10.x.x
When using PM2 with nvm, ensure PM2 is also installed under the nvm-managed Node
install: npm install -g pm2 (after activating nvm). The startup script
generated by pm2 startup will reference the correct node binary.
Step 3 — Install PostgreSQL 16
Add the official PostgreSQL apt repository and install version 16.
$ sudo apt install -y postgresql postgresql-contrib
Start PostgreSQL and enable it on boot.
$ sudo systemctl enable postgresql $ sudo systemctl start postgresql
Create a database and user for RestroAgent.
$ sudo -u postgres psql -- Inside psql: CREATE USER restroagent WITH PASSWORD 'your_strong_password'; CREATE DATABASE restroagent OWNER restroagent; GRANT ALL PRIVILEGES ON DATABASE restroagent TO restroagent; \q
your_strong_password with a
long random password. Store it securely — you will need it for the
DATABASE_URL environment variable.
Step 4 — Deploy the Application
Option A — Git clone (recommended for teams and ongoing updates)
If you host the source code in a private git repository (GitHub, GitLab, Bitbucket), clone
it directly onto the server. This makes future updates a one-command git pull.
$ sudo mkdir -p /var/www $ sudo chown restroagent:restroagent /var/www $ cd /var/www $ git clone https://github.com/your-org/restroagent.git restroagent $ cd restroagent
For a private repository, use an SSH deploy key or a personal access token.
Example with token: git clone https://TOKEN@github.com/your-org/restroagent.git
Option B — ZIP upload (direct CodeCanyon download)
You received a ZIP file (RestroAgent-v1.0.zip) with your CodeCanyon purchase.
Upload it to your server and extract it.
$ sudo mkdir -p /var/www $ cd /var/www $ unzip /path/to/RestroAgent-v1.0.zip $ mv RestroAgent restroagent $ cd restroagent
Install dependencies
Run this inside the restroagent/ directory.
$ npm install
This may take 1–3 minutes on first run as all packages are downloaded from npm. Ensure your server has internet access.
Step 5 — Configure Environment Variables
Copy the example file and fill in your values.
$ cp .env.example .env $ nano .env
Required variables
| Variable | Description | |
|---|---|---|
DATABASE_URL |
PostgreSQL connection string. Example:
postgresql://restroagent:password@localhost:5432/restroagent
|
REQUIRED |
NEXT_PUBLIC_APP_URL |
Full public URL of your app with no trailing slash. Example:
https://yourdomain.com
|
REQUIRED |
NEXT_PUBLIC_SITE_URL |
Same as above — used by auth routes. | REQUIRED |
WEBHOOK_BASE_URL |
Publicly reachable HTTPS URL used by Twilio webhooks. Must match
NEXT_PUBLIC_APP_URL.
|
REQUIRED |
JWT_SECRET |
Long random string for signing session tokens. Minimum 64 characters. | REQUIRED |
ENCRYPTION_KEY |
32-byte hex string for encrypting sensitive DB fields. | REQUIRED |
OPENAI_API_KEY |
Your OpenAI API key beginning with sk-. |
REQUIRED |
SMTP_HOST |
SMTP server hostname. | REQUIRED |
SMTP_PORT |
SMTP port — typically 587 for TLS. |
REQUIRED |
SMTP_USER |
SMTP login username or email address. | REQUIRED |
SMTP_PASS |
SMTP password. | REQUIRED |
SMTP_FROM |
The "From" address for outgoing emails. | REQUIRED |
NODE_ENV |
Set to production on live deployments. |
REQUIRED |
Generate secure keys
Use these one-liners to generate cryptographically strong keys directly on your server.
# Generate JWT_SECRET (64-byte hex) $ node -e "console.log(require('crypto').randomBytes(64).toString('hex'))" # Generate ENCRYPTION_KEY (32-byte hex) $ node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
Stripe variables
| Variable | Description | |
|---|---|---|
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY |
Stripe publishable key (pk_live_...) |
OPTIONAL |
STRIPE_SECRET_KEY |
Stripe secret key (sk_live_...) — never expose publicly |
OPTIONAL |
STRIPE_WEBHOOK_SECRET |
Stripe webhook signing secret (whsec_...) |
OPTIONAL |
Twilio variables
| Variable | Description | |
|---|---|---|
TWILIO_ACCOUNT_SID |
Twilio Account SID from your console dashboard | OPTIONAL |
TWILIO_AUTH_TOKEN |
Twilio Auth Token — keep secret | OPTIONAL |
TWILIO_PHONE_NUMBER |
Your Twilio number in E.164 format, e.g. +15551234567 |
OPTIONAL |
.gitignore file
already excludes .env. Keep your secret keys private.
Step 6 — Build the Application
Compile the Next.js application for production. This step outputs optimised static files
to the .next/ directory.
$ npm run build
The build process can take 3–8 minutes depending on your server's CPU. Once complete you will see a summary of all generated pages and their sizes.
Test the server runs correctly before setting up PM2.
$ npm start # starts on port 5000 by default
Visit http://your-server-ip:5000 in your browser. If you see the RestroAgent
landing page, the build is working. Press Ctrl+C to stop before continuing.
Custom port
Set the PORT environment variable to use a different port.
$ PORT=3000 npm start
Step 7 — Set Up PM2 (Process Manager)
PM2 keeps the application running in the background, restarts it automatically if it crashes, and survives server reboots.
If you installed Node.js via nvm, install PM2 under the same nvm-managed version
(do not use sudo, which would install under the system
Node instead of nvm).
$ npm install -g pm2
Start the application under PM2.
$ pm2 start npm --name "restroagent" -- start
Save the PM2 process list and generate a startup script so it auto-starts on reboot.
$ pm2 save $ pm2 startup # follow the printed sudo command to register the service
Useful PM2 commands.
$ pm2 status # view all running processes $ pm2 logs restroagent # stream application logs $ pm2 restart restroagent # restart the app after code changes $ pm2 stop restroagent # stop the app
Step 8 — Configure Nginx as a Reverse Proxy
Nginx sits in front of Node.js, handles SSL termination, serves static files efficiently, and forwards all other requests to the app.
$ sudo apt install -y nginx
Create a new site configuration.
$ sudo nano /etc/nginx/sites-available/restroagent
Paste the following, replacing yourdomain.com with your actual domain.
server {
listen 80;
server_name yourdomain.com www.yourdomain.com;
# Increase body size limit for file uploads (logos, docs, etc.)
client_max_body_size 50M;
location / {
proxy_pass http://127.0.0.1:5000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
proxy_read_timeout 86400; # needed for long-lived WebSocket connections
}
}
Enable the site and reload Nginx.
$ sudo ln -s /etc/nginx/sites-available/restroagent /etc/nginx/sites-enabled/ $ sudo nginx -t # test configuration — should say "syntax is ok" $ sudo systemctl reload nginx
The proxy_read_timeout 86400 setting is important for the Twilio voice
WebSocket connections. Without it, long calls may be silently dropped.
Step 9 — Install SSL Certificate (Let's Encrypt)
Twilio and Stripe both require a publicly accessible HTTPS URL. Install a free SSL certificate via Certbot.
$ sudo apt install -y certbot python3-certbot-nginx $ sudo certbot --nginx -d yourdomain.com -d www.yourdomain.com
Follow the prompts — Certbot will automatically update your Nginx config for HTTPS and set up certificate auto-renewal. Verify renewal works.
$ sudo certbot renew --dry-run
After completing this step, update your .env file to use the
https:// URL.
NEXT_PUBLIC_APP_URL=https://yourdomain.com NEXT_PUBLIC_SITE_URL=https://yourdomain.com WEBHOOK_BASE_URL=https://yourdomain.com
Then rebuild and restart.
$ npm run build $ pm2 restart restroagent
Step 10 — Configure Stripe Webhooks
Stripe sends webhook events to your server to update subscription statuses when payments succeed, fail, or are cancelled.
- Log in to the Stripe Dashboard
- Go to Developers → Webhooks → Add endpoint
-
Set the endpoint URL to:
https://yourdomain.com/api/billing/stripe-webhook -
Under Events to listen to, select:
customer.subscription.createdcustomer.subscription.updatedcustomer.subscription.deletedcheckout.session.completed
-
Click Add endpoint, then copy the
Signing secret (
whsec_...) - Add it to your
.env:STRIPE_WEBHOOK_SECRET=whsec_... -
Rebuild and restart:
npm run build && pm2 restart restroagent
You can test webhook delivery from the Stripe Dashboard using
Send test webhook. Check PM2 logs with
pm2 logs restroagent to confirm events are being received.
Step 11 — Database Schema & First Login
The database schema is initialised automatically the first time the seed
endpoint is called. All tables, enums, and indexes defined in the Drizzle ORM schema
(src/server/db/schema/schema.ts) are created if they do not yet exist —
there is nothing to run manually in psql.
Seed the demo accounts
Call the seed endpoint once after deployment to initialise the database schema and create
the two starter accounts. In production the endpoint requires the
x-seed-secret header matching the SEED_SECRET value you set in
.env.
$ curl -X POST https://yourdomain.com/api/auth/seed-demo-users \
-H "x-seed-secret: your-seed-secret-value"
The endpoint creates two starter accounts — one super admin and one restaurant owner —
using the seed identifiers defined in src/app/api/auth/seed-demo-users/route.ts.
The exact email and password values are intentionally not reproduced here so that this
documentation stays neutral across deployments.
src/app/api/auth/seed-demo-users/route.ts (and the matching constants in
src/lib/demoMode.ts) to use email addresses on a domain you control, then
re-run the seed endpoint.
Access the admin panel
Navigate to https://yourdomain.com/admin and sign in with the super admin
credentials defined in your seed file. Change the password on first login.
Production Go-Live Checklist
JWT_SECRETis at least 64 random charactersENCRYPTION_KEYis a 32-byte (64 hex character) random valueSEED_SECRETis set and you have noted the value to use with the seed curl command-
NEXT_PUBLIC_APP_URLandWEBHOOK_BASE_URLpoint to your public HTTPS domain NODE_ENV=productionis set in.env- PostgreSQL is accessible from the app server
- Nginx reverse proxy is configured and running
- SSL certificate is installed and auto-renewal is working
-
Stripe webhook endpoint is registered and
STRIPE_WEBHOOK_SECRETis set - Demo user passwords changed after first login
- PM2 startup script generated so app survives reboots
- Firewall configured — only ports 22, 80, 443 open publicly
- SMTP credentials verified — test email can be sent
- Twilio phone number purchased and linked to an AI agent in the dashboard
File Storage Configuration
RestroAgent stores uploaded files (restaurant logos, favicons, widget icons, knowledge-base documents) using a configurable storage driver. Two drivers are available: local disk (default) and S3-compatible object storage. Choose the driver that suits your hosting environment.
Local Disk Storage (default)
Files are written to the public/uploads/ directory on the server's local
disk and served by Next.js as static assets at
/uploads/<folder>/<filename> (e.g.
/uploads/logos/your-logo.png).
When to use local storage
- Traditional VPS deployments — the server has a persistent local disk and files survive restarts.
- Single-server setups — there is only one application process and the filesystem is not ephemeral.
Configuration
STORAGE_DRIVER=local # this is the default — no other vars required
S3-Compatible Object Storage
Files are uploaded to an S3-compatible bucket and served from its public URL. This driver is required for containerised deployments and strongly recommended for any cloud or multi-instance setup because it stores files independently of the server.
Compatible providers
| Provider | Notes |
|---|---|
| AWS S3 | Set S3_REGION; leave S3_ENDPOINT blank (AWS default endpoint used). |
| DigitalOcean Spaces | Set S3_ENDPOINT=https://<region>.digitaloceanspaces.com and use your Space's CDN URL as S3_PUBLIC_URL. |
| Cloudflare R2 | Set S3_ENDPOINT=https://<account-id>.r2.cloudflarestorage.com. R2 does not support ACLs — bucket policy controls public access. |
| MinIO | Self-hosted S3-compatible storage. Set S3_ENDPOINT=https://minio.yourdomain.com. |
Environment variables
| Variable | Description | |
|---|---|---|
STORAGE_DRIVER |
Set to s3 to enable S3-compatible storage. |
REQUIRED |
S3_BUCKET |
The name of your bucket (e.g. my-restroagent-uploads). |
REQUIRED |
S3_REGION |
AWS region or Spaces region (e.g. us-east-1, nyc3). |
REQUIRED |
S3_ACCESS_KEY |
Access key ID / API key for your bucket. | REQUIRED |
S3_SECRET_KEY |
Secret access key for your bucket. | REQUIRED |
S3_ENDPOINT |
Custom endpoint URL for non-AWS providers. Leave blank for AWS S3. | OPTIONAL |
S3_PUBLIC_URL |
Public base URL for serving uploaded files (CDN URL or public bucket URL).
Strongly recommended — without it the app auto-derives a URL which may not be
publicly accessible. Example:
https://your-bucket.nyc3.cdn.digitaloceanspaces.com
|
RECOMMENDED |
Bucket policy — making uploads publicly readable
The app does not set object ACLs — public access is controlled entirely
by your bucket policy. For images to be displayed in browsers, the bucket (or the specific
uploads/ prefix) must allow anonymous GetObject access. Consult
your provider's documentation for the exact policy format:
Example: DigitalOcean Spaces
STORAGE_DRIVER=s3 S3_BUCKET=my-restroagent S3_REGION=nyc3 S3_ACCESS_KEY=DO00XXXXXXXXXXXX S3_SECRET_KEY=yourSpacesSecretKey S3_ENDPOINT=https://nyc3.digitaloceanspaces.com S3_PUBLIC_URL=https://my-restroagent.nyc3.cdn.digitaloceanspaces.com
Example: Cloudflare R2
STORAGE_DRIVER=s3
S3_BUCKET=restroagent-uploads
S3_REGION=auto
S3_ACCESS_KEY=your_r2_access_key_id
S3_SECRET_KEY=your_r2_secret_access_key
S3_ENDPOINT=https://<account-id>.r2.cloudflarestorage.com
S3_PUBLIC_URL=https://assets.yourdomain.com # custom domain on R2
After changing STORAGE_DRIVER you must rebuild the application:
npm run build && pm2 restart restroagent. Existing uploads stored
on local disk are not automatically migrated to S3.
Detailed Feature Reference
📞 AI Voice Agent
The AI Voice Agent is the centrepiece of RestroAgent. When a customer calls the restaurant's Twilio phone number, the call is answered in real time by an AI agent that speaks naturally, understands speech, and can take orders, check availability, confirm reservations and answer questions — all without any human involvement.
How it works
- A customer calls the Twilio number assigned to the restaurant.
- Twilio triggers a webhook to the RestroAgent server and opens a Media Stream WebSocket.
- Real-time audio is streamed to OpenAI's Realtime API, which handles speech-to-text, reasoning, and text-to-speech simultaneously.
- The AI agent has access to tools — it can create orders, check menu availability, look up booking slots, and search the restaurant's knowledge base.
- The completed order or booking is saved to the database and appears in the dashboard instantly.
Configuration (per restaurant)
- Phone number — Purchase a Twilio number from the AI Agent Config → Phone Numbers page.
- System prompt — Customise the agent's personality, greeting style, and operational constraints.
- Voice & TTS — Choose the voice model (OpenAI Alloy/Echo/Shimmer or ElevenLabs custom voice).
- Agent role — Set the agent's specialisation: orders, reservations, general Q&A, or a combination.
- Language — The agent can converse in multiple languages based on caller input.
Call logs
Every call is logged with caller ID, duration, transcript summary, and outcome (order created, booking confirmed, escalated to human, etc.). Access via Telephone → Call Logs.
Human escalation
If the AI cannot resolve a query, or if the caller requests a human, the conversation is escalated. Staff are notified via in-app alert and the conversation status is changed to human.
💬 AI Chat Widget
The embeddable chat widget allows restaurants to add an AI chat assistant to their existing website with a single script tag. The widget opens as a floating bubble and handles the same tasks as the voice agent — orders, bookings, FAQs — through a text chat interface.
Embedding the widget
Copy the embed script from Widget Settings and paste it before the closing
</body> tag of your website.
<script src="https://yourdomain.com/api/widget/embed.js" data-restaurant-id="your-restaurant-id" defer ></script>
Customisation options
- Widget icon — Upload a custom icon image for the chat bubble.
- Brand colour — Set the primary colour to match the restaurant's brand.
- Greeting message — Configure the first message shown to visitors.
- AI model — Choose from any model configured in Admin → LLM Providers (GPT-4o, OpenRouter-routed models, etc.).
- Position — Bottom-right (default) or bottom-left.
Conversation flow
Each widget session creates a Conversation record linked to the restaurant. Messages are stored and viewable in the Conversations dashboard. Staff can take over any chat session by switching its status from AI to human-managed.
🛒 Order Management
The Orders module provides a real-time view of all incoming orders, regardless of whether they arrived through a voice call, the chat widget, or manual entry.
Order lifecycle
| Status | Description |
|---|---|
| Pending | Order received, awaiting confirmation by staff. |
| Confirmed | Order accepted and passed to the kitchen. |
| Kitchen | Order is being prepared. |
| Ready | Order is ready for pickup or dispatch. |
| Rider | Order collected by delivery rider. |
| Delivered | Order delivered to customer. |
| Completed | Order fully completed and closed. |
| Cancelled | Order cancelled. |
| Escalated | Flagged for staff attention. |
Features
- Real-time updates — order statuses update live without page refresh.
- Channel filter — filter by chat, voice, WhatsApp, email, SMS.
- Order detail drawer — click any order to view line items, modifiers, customer info and status history.
- Manual order creation — staff can create orders directly from the dashboard.
- Branch scope — orders are scoped to the currently selected branch.
📅 Table Booking Management
The booking module handles the full lifecycle of restaurant table reservations — from initial request to guest arrival and completion.
Booking statuses
- Pending — reservation requested, awaiting confirmation.
- Confirmed — reservation accepted and confirmed to the customer.
- Reminder Sent — automatic reminder dispatched before the booking time.
- Seated — guest has arrived and is at the table.
- Completed — dining experience finished.
- No Show — guest did not arrive.
- Cancelled — booking cancelled by restaurant or customer.
Features
- Timeline view — visual calendar layout showing bookings across the day.
- Multi-status filters — quickly filter to only pending, only confirmed, etc.
- VIP tagging — mark important guests for special treatment.
- Guest notes — record dietary requirements, allergies and preferences per booking.
- Party size & seating — record the number of guests and preferred seating area.
- Automated reminders — email reminders sent automatically before the reservation time.
👤 Customer CRM
Every customer who interacts with the restaurant — through voice, chat widget, or direct entry — is stored in a unified customer profile.
Customer profile contains
- Name, email address, phone number.
- Full order history with total spend.
- All table booking records.
- Conversation and call history.
- First seen and last active timestamps.
- Internal notes left by staff.
Uses
Customer profiles power personalised AI interactions — when a returning customer calls, the AI agent can reference their previous orders to speed up the ordering process.
📚 Knowledge Base
The knowledge base is a per-restaurant repository of information fed to the AI agent as context. It lets you teach the agent about things not covered by the menu — opening hours, allergen policies, delivery zones, parking, special events, loyalty programmes and more.
Knowledge base entry types
| Type | Description |
|---|---|
| Article | Rich-text article — write general information directly in the browser editor. |
| Q&A | Explicit question-and-answer pair — ideal for FAQs like "Do you have parking?" or "What are your opening hours?" |
| Document | Upload a PDF or text file (allergen menu, policies, price list). |
| URL | Provide a public URL — the system fetches and indexes the page content. |
Usage
Navigate to Knowledge Base in the dashboard, click Add Entry, select the type, and save. The agent uses the entries on every query via semantic search — it will retrieve the most relevant entries and include them in its context window before responding.
🏪 Multi-Branch Support
A single restaurant account can manage multiple physical locations (branches). Each branch operates independently with its own:
- AI agent configuration and phone number.
- Menu (can differ from other branches).
- Orders and bookings.
- Staff members and access permissions.
- Operating hours and settings.
Switching branches
Users with access to multiple branches can switch the active branch using the branch switcher in the top navigation bar. All dashboard views (orders, bookings, conversations) automatically scope to the selected branch.
Managing branches
Owners and managers can create and edit branches from Branch Management. Each branch can be given a name, address, phone number, and its own set of operating parameters.
💰 Billing & Subscription Plans
RestroAgent ships with a complete Stripe-powered SaaS billing system that lets platform operators charge restaurant clients for access.
Plan management (Super-Admin)
- Create unlimited billing plans with custom names, pricing tiers, feature lists and limits.
- Each plan links to a Stripe Product and monthly/annual Price IDs.
- Set per-plan limits (max branches, max AI agents, max monthly conversations, etc.).
- Toggle plans active/inactive without deleting them.
Restaurant billing (Restaurant owner)
- Owners can view their current plan, usage metrics and billing history from Billing.
- Upgrade, downgrade or cancel directly through the Stripe billing portal.
- View all past invoices and download PDFs.
- Monthly/annual toggle with automatic price display.
- 14-day free trial available on supported plans.
Subscription statuses
Plans track status: Active, Trial, Past Due, Cancelled. Stripe webhook events keep the database in sync automatically.
🔧 Super-Admin Panel
The super-admin panel (/admin) is a dedicated control interface for the
platform operator — the person who runs the RestroAgent SaaS business. It is completely
separate from the restaurant owner dashboard.
Admin panel sections
| Section | What you can do |
|---|---|
| Dashboard | Platform-wide KPIs — total restaurants, active subscriptions, revenue, conversations, orders and system health. |
| Restaurants | List all tenants, view their subscription status, impersonate them for support, suspend or delete accounts. |
| Billing Plans | Create and manage subscription plans, link to Stripe prices, set feature limits. |
| AI Settings | Configure global LLM providers (OpenAI, OpenRouter, ElevenLabs, Deepgram, Sarvam AI) and manage API keys. |
| LLM Providers | Define which AI models are available to restaurant owners in their agent config. |
| Languages | Enable/disable languages for the dashboard UI and trigger AI-powered translation generation. |
| Branding | Update platform name, logo and primary colour (white-label support). |
| Audit Logs | Complete immutable audit trail of all admin and support actions. |
| Support Tickets | Manage support requests from restaurant owners with priority and status tracking. |
| Platform Analytics | Aggregated usage data across all tenants — API calls, conversations, orders, bookings per time period. |
| Blog | Built-in blog/content management for the platform's landing pages. |
| Notifications | Send platform-wide or targeted notifications to restaurant owners. |
User impersonation
Admins and support staff can impersonate any restaurant owner account to troubleshoot issues without needing their password. All impersonation sessions are logged in the audit trail. Exit impersonation at any time using the banner shown at the top of the dashboard.
🔔 Alerts & Notifications
RestroAgent has a real-time in-app notification system that keeps restaurant staff informed of important events without requiring a separate tool.
Notification types
- Order alerts — new order received, order status changed, order escalated.
- Booking alerts — new booking received, booking reminder due, booking cancelled.
- AI alerts — AI agent escalated a call or chat to human review.
- Billing alerts — subscription renewal, payment failed, trial expiring.
- Staff alerts — new staff member added, role changed.
- System alerts — platform announcements from the super-admin.
Browser audio alerts
When a new order arrives, an audible chime plays in the browser — useful for kitchen staff who may not be watching the screen. This can be enabled/disabled per user in Alert Settings.
Notification preferences
Each user can configure which notification types they receive and via which channels (in-app, email) from the Notification Preferences page.
👥 Staff Management & Roles
RestroAgent has a flexible role-based access control (RBAC) system. The restaurant owner can create staff accounts and assign granular permissions using custom roles.
Built-in roles
- Owner — full access to all features including billing and staff management.
- Manager — access to all operational features; cannot manage billing or delete the account.
- Staff — limited access defined by the owner (e.g. orders only, or bookings only).
Custom roles
Owners can create custom roles with fine-grained permission sets. Each permission can be toggled on or off per role — for example, a "Kitchen Display" role might have access only to the orders view.
Branch-scoped access
Staff members can be assigned to specific branches. A staff member assigned to Branch A will only see data for Branch A.
🔌 REST API & Webhooks
API Keys
Restaurant owners can generate API keys from Settings → REST API. API keys allow external systems (POS terminals, kiosk apps, third-party integrations) to interact with RestroAgent data programmatically — creating orders, checking booking availability, querying menus, etc.
Outbound Webhooks
Configure outbound webhooks from Settings → Webhooks. When events occur in RestroAgent (new order, booking status change, conversation escalated), the system sends an HTTP POST request to your configured endpoint with a JSON payload. This enables integration with virtually any external system — kitchen display systems, delivery platforms, CRM tools, analytics pipelines.
Supported webhook events
order.created— a new order was placed.order.status_changed— order status moved to a new step.booking.created— a new reservation was made.booking.status_changed— booking status changed.conversation.escalated— AI handed off to human.
Delivery logs
Every outbound webhook delivery is logged with the HTTP response code, response body and timestamp. Failed deliveries are visible in Webhooks → Delivery Logs so you can debug integration issues.
Message Templates
Create reusable message templates from Settings → Templates. Templates are used by the AI agent for common responses and can be customised per language.
📊 Analytics
Restaurant analytics
Each restaurant gets its own analytics dashboard (Analytics) showing:
- Total orders, revenue, average order value over time.
- Booking volume, confirmation rate, no-show rate.
- Conversation volume by channel (voice vs chat).
- AI resolution rate vs human escalation rate.
- Top-ordered menu items.
Platform analytics (Super-Admin)
Platform operators get aggregated metrics across all tenants:
- Active restaurants and growth over time.
- Platform-wide API usage and LLM token consumption.
- Revenue from subscriptions.
- Support ticket volume and resolution times.
🗨 Conversations (Omnichannel Inbox)
The Conversations inbox provides a single, unified view of every interaction a customer has had with the restaurant — across all channels. Whether a customer contacted the restaurant by voice call, the embedded chat widget, WhatsApp, email, or SMS, every conversation thread appears in one place under Conversations.
What it does
- Unified list — all chat and voice conversations in a single paginated table, sortable and filterable by status (AI Handling, Needs Agent, Resolved) and channel.
- Conversation detail panel — click any row to open a slide-over showing the full message transcript, customer contact info (name, email, phone), assigned agent, AI confidence score, and linked order or booking.
- Human takeover — a staff member can take over any AI-managed conversation at any time by clicking Take Over from AI. The conversation status changes to Needs Agent and the staff member is recorded as the assigned agent.
- Mark resolved — once a conversation is handled, it can be marked Resolved to remove it from the active queue.
- Bulk actions — select multiple conversations to bulk-resolve or bulk-delete.
- Call logs tab — a dedicated Calls tab lists every voice call with direction (inbound/outbound), duration, and a transcript viewer for calls with recorded audio.
- CSV export — export the current filtered view to a CSV file for off-platform reporting.
- Live polling — the conversation list refreshes automatically every 30 seconds so staff always see the latest state without manually refreshing.
Setup
No additional setup is required beyond configuring your AI agents (voice and/or chat). All conversations created by agents automatically appear in this view. The Conversations page is accessible to staff roles that have the conversations permission enabled.
💚 WhatsApp Integration
RestroAgent integrates with the WhatsApp Business Platform (Meta) to send and receive WhatsApp messages for order updates, booking confirmations, and marketing campaigns. Each branch can have its own WhatsApp Business Account (WABA) connected independently.
How it works
- A customer sends a WhatsApp message to the restaurant's WhatsApp Business number.
- Meta delivers the message to RestroAgent via the registered webhook URL.
- The AI agent processes the message, takes action (place order, check booking, answer FAQ), and replies within the same thread.
- All messages are recorded in the Conversations inbox.
- For outbound-initiated messages (marketing campaigns, order notifications) RestroAgent uses pre-approved WhatsApp Message Templates.
Setup steps
-
Create a Meta Business account and app
Go to developers.facebook.com, create a Business app, and add the WhatsApp product to it.
-
Add a phone number to your WABA
In the Meta app dashboard under WhatsApp → Getting Started, add or register a phone number. Note the Phone Number ID shown on that page.
-
Generate a permanent access token
Create a System User in Business Settings, assign it full control of the WhatsApp asset, and generate a permanent access token for that System User.
-
Enter credentials in RestroAgent
Navigate to Settings → Channels → WhatsApp. Enter the Phone Number ID, Access Token, WhatsApp Business Account ID, and a Verify Token (a secret string you choose).
-
Register the webhook
In the Meta app under WhatsApp → Configuration, set the Webhook URL to:
https://yourdomain.com/api/channels/whatsapp/webhook/[branchId]
Enter the same Verify Token you configured in step 4. Subscribe to the
messageswebhook field. -
Set the App Secret (optional but recommended)
Copy your Meta app's App Secret from the app dashboard and enter it in the WhatsApp settings page. This enables signature verification on incoming webhooks for production security.
Credential fields
| Field | Where to find it | Required |
|---|---|---|
| Phone Number ID | Meta app → WhatsApp → Getting Started | YES |
| Access Token | System User permanent token | YES |
| WABA ID | Meta Business Suite → WhatsApp accounts | YES |
| Verify Token | You choose — must match what you enter in Meta webhook config | YES |
| App Secret | Meta app → Settings → Basic | OPTIONAL |
24-hour messaging window
WhatsApp Business API enforces a 24-hour messaging window: you can send free-form messages to a customer only within 24 hours of their last inbound message. After the window closes, all outbound messages must use a pre-approved Message Template. RestroAgent's marketing campaign feature handles this automatically — WhatsApp campaigns always send via templates.
Template messages
Create and submit message templates for approval in the Meta Business Manager. Once approved,
sync them into RestroAgent from Marketing → Campaigns → New campaign → Step 3 → Sync from Meta.
Templates can include variable placeholders (e.g. {{1}} for the customer's name)
which RestroAgent fills in at send time.
Webhook delivery log
Every inbound and outbound WhatsApp message is recorded in the
WhatsApp message log (whatsapp_message_log table). Operators
can inspect message history, delivery statuses, and failures via the
WhatsApp → Message Log page in the dashboard (backed by
GET /api/channels/whatsapp/log?branch_id=…).
Key statuses tracked in the log:
| Status | Meaning |
|---|---|
sent | Message delivered to the WhatsApp Cloud API successfully. |
delivered | Meta confirmed delivery to the customer's device. |
read | Customer has opened the message (read receipts enabled). |
failed | Delivery failed — check the error code returned by Meta. |
received | Inbound message from the customer processed by the webhook. |
The log is paginated and capped at 100 recent entries per branch. For longer-term audits, export conversations as CSV from the Conversations inbox.
📱 QR Storefront
The QR Storefront is a public-facing, mobile-first ordering system that lets restaurant customers scan a QR code at their table, browse the live menu, add items to a cart, apply loyalty points or coupon codes, and place an order — all from their own phone, with no app download required.
How customers use it
- A QR code printed on the table is scanned with the phone's camera.
- The browser opens the storefront at
https://yourdomain.com/r/[restaurantSlug]/[branchSlug]. - The customer browses the live menu (same data as the dashboard Menu Management).
- Items are added to a cart. Optional: enter a loyalty phone number to redeem points or enter a coupon code.
- The customer submits the order. It appears immediately in the Orders dashboard with the source marked as storefront.
Features
- Live menu — reflects real-time availability; items toggled off in Menu Management are hidden instantly.
- Dietary filters — customers can filter by vegan, gluten-free, halal, and other dietary flags.
- Coupon redemption — customers enter a coupon code at checkout; the discount is validated and applied in real time.
- Loyalty redemption — customers enter their phone number to look up their loyalty balance and choose how many points to redeem.
- Gift card redemption — customers can apply a gift card code at checkout.
- Per-branch storefront — each branch has its own unique storefront URL and QR code, with its own menu and settings.
- No login required — customers do not need an account to browse and order.
Where to find the storefront URL and QR code
Navigate to Storefront in the dashboard sidebar. The hub page shows each branch's unique storefront URL, a live QR code preview, and a link to the Tables page where per-table QR codes can be generated and printed.
The storefront is feature-gated. If your subscription plan does not include the
storefront feature, the dashboard page will show an upgrade prompt.
The public /r/[restaurantSlug]/[branchSlug] routes are always accessible once a branch slug
is configured.
🪑 Table Management
Table Management lives under Branch Management → [Branch] → Tables and gives restaurant operators a complete list of physical tables at each branch. Each table is linked to a unique QR code that points directly to the QR Storefront for that table.
Features
- Add / edit / delete tables — assign a table number or name (e.g. "Table 5", "Terrace A", "Private Room") and an optional capacity.
- Unique QR code per table — each table gets its own QR code that encodes the branch storefront URL plus the table identifier. When a customer scans it, the order they place is automatically tagged with that table.
- Printable QR sheet — generate a printable A4 sheet containing all QR codes for a branch in a single click. Each QR tile shows the table name and the storefront URL for reference.
- Booking linkage — tables are also selectable when creating a booking, so the booking record records which table the party will be seated at.
- Storefront integration — orders placed via a table's QR code are tagged with that table in the Orders dashboard, so kitchen staff know exactly which table each order belongs to.
Setup
Go to Branch Management, select a branch, and open the Tables tab. Click Add table, enter the table name and capacity, and save. QR codes are generated automatically and are immediately ready for printing.
⭐ Loyalty Program
RestroAgent includes a built-in tiered loyalty system that rewards repeat customers with points they can redeem against future orders at the QR Storefront.
How it works
- A customer places an order through the QR Storefront and provides their phone number.
- The platform awards loyalty points based on the order value and the configured earning rate.
- The customer's points balance accumulates across all orders.
- On future visits, the customer enters their phone number at checkout, sees their balance, and can choose to redeem some or all of their points for a discount.
Configuration
Navigate to Loyalty in the dashboard to configure the program:
| Setting | Description |
|---|---|
| Earning rate | How many points a customer earns per unit of currency spent (e.g. 1 point per $1). |
| Redemption rate | How many points equal one unit of currency discount (e.g. 100 points = $1 off). |
| Minimum redemption | Minimum number of points required before a customer can redeem. |
| Tiers | Define named tiers (e.g. Bronze, Silver, Gold) with point thresholds. Customers automatically advance to higher tiers as their lifetime points grow. |
| Tier benefits | Optional bonus earning multipliers or exclusive perks per tier (e.g. Gold members earn 2× points). |
Customer view
A customer's current points balance, tier status, and full transaction history are visible on their profile page in the Customer CRM (Customers → [Customer]). Staff can also make manual point adjustments from this page (for example, to credit points for an in-store purchase).
🎁 Gift Cards
Restaurant owners can issue digital gift cards that customers can purchase, share, and redeem at the QR Storefront checkout.
Issuance
Navigate to Gift Cards and click Issue gift card. Set the initial value, an optional expiry date, and optionally link the card to a specific customer. The platform generates a unique alphanumeric code for each card.
Distribution
The gift card code is shown immediately after creation and can be copied and shared with the recipient via any channel (email, WhatsApp, SMS). RestroAgent does not automatically send the code — the restaurant owner is responsible for delivering it.
Redemption
At the QR Storefront checkout, the customer enters their gift card code. The platform validates the code, shows the remaining balance, and deducts the order amount from the card. If the order total exceeds the card balance, the customer pays the remainder through any other available method.
Balance ledger
Every transaction against a gift card (issuance, redemption, top-up) is recorded in the balance ledger, accessible from the Gift Cards list view by clicking a card. The admin can view all cards, their current status (active, depleted, expired), and the remaining balance.
🏷 Coupons & Discounts
The Coupons module lets restaurant operators create promotional discount codes that customers can apply at the QR Storefront checkout.
Coupon types
| Type | Description |
|---|---|
| Flat discount | Deducts a fixed amount from the order total (e.g. $5 off). |
| Percentage discount | Deducts a percentage of the order total (e.g. 15% off). |
| Free item | Adds a specified menu item to the cart at no charge. |
Coupon settings
- Code — custom or auto-generated alphanumeric code.
- Minimum order value — coupon only applies when the cart total meets a threshold.
- Per-customer usage limit — limit how many times a single customer can use this coupon.
- Total usage limit — cap the total number of times the coupon can be redeemed across all customers.
- Expiry date — the coupon is automatically invalidated after this date.
- Active / inactive toggle — enable or disable a coupon at any time without deleting it.
Usage tracking
The Coupons list view shows each coupon's total redemption count and remaining uses. Click a coupon to see the full usage history including which customer used it, the order it was applied to, and the discount value given.
📣 Marketing — Audiences & Campaigns
The Marketing module lets restaurant operators build targeted customer segments (Audiences) and send broadcast messages to those segments via Campaigns over email and WhatsApp.
Audiences
Navigate to Marketing → Audiences to create reusable customer segments. Each audience is defined by a set of filter rules:
- Order recency — customers who placed an order within N days.
- Order count — customers with at least N orders.
- Lifetime spend — customers who have spent above a threshold.
- Loyalty tier — customers at a specific tier (Bronze, Silver, Gold).
- Branch — filter to customers who have ordered from a specific branch.
- Channel — filter to customers reachable via email or WhatsApp (or any).
A live preview count updates as you adjust filters, showing how many customers currently match. Audiences are re-evaluated at campaign launch time, so the latest customer state is always used.
Quick-start templates
Four built-in audience templates are available to get you started quickly:
- VIP regulars — 5+ orders in the last 90 days.
- Big spenders — lifetime spend above a threshold.
- Win back lapsed — at least 1 order, none in the last 180 days.
- Newcomers — first order within the last 30 days.
Campaigns
Navigate to Marketing → Campaigns and click New campaign to open the four-step wizard:
- Channel — choose Email, WhatsApp, or Email + WhatsApp (sends a linked pair).
- Audience — pick a saved Audience or define ad-hoc rules inline.
- Content — compose the email (subject + HTML body) and/or select a WhatsApp approved template with variable values.
- Review & schedule — send immediately or schedule for a specific date and time. Optional: configure per-minute / per-hour send rate caps.
Campaign statuses
| Status | Description |
|---|---|
| Draft | Campaign created but not yet launched. |
| Scheduled | Campaign queued to send at a future time. |
| Sending | Dispatcher is actively sending messages. |
| Completed | All messages dispatched. |
| Cancelled | Campaign was cancelled before completion. |
| Failed | Campaign encountered a fatal error. |
Delivery statistics
Click any completed campaign to view the delivery report: total sent, delivered, failed, and (for email) open rate. The individual delivery log shows the status of every message sent to every recipient and can be exported as a CSV.
🌍 Multi-Language Support
RestroAgent includes a database-backed localisation system that allows the entire dashboard UI to be translated into any language. All UI strings are stored in the database rather than in code, making it possible to add or update translations at runtime without redeploying the application.
Admin language management
Navigate to Admin → Languages to manage the platform's language catalogue:
- Enable a language — add a language (e.g. Arabic, French, Spanish) by selecting it from the list and toggling it active.
- AI-powered translation — click Auto-translate on any enabled language to trigger an OpenAI-powered bulk translation of every UI string key into that language. This populates the entire translation catalogue in seconds.
- Manual editing — individual translation keys can be reviewed and edited inline for any language.
- Default language — set the fallback language used when a translation key is missing in the selected language.
RTL support
Right-to-left languages (Arabic, Hebrew, Farsi) are handled automatically. When a user selects one of these languages, the dashboard layout switches to RTL and all directional CSS is mirrored accordingly.
Per-user language selector
Each dashboard user can select their preferred language from the profile menu. The selection is stored in their session and persists across logins.
Storefront language
The public QR Storefront uses the same translation system as the dashboard. When a restaurant has a non-English language active, storefront-facing strings (menu categories, checkout labels, etc.) are served in the configured language.
Adding a new language manually
- Go to Admin → Languages and click Add language.
- Enter the ISO 639-1 code (e.g.
de) and display name (e.g.Deutsch). - Toggle the language active.
- Use Auto-translate or manually enter translations for each key.
✉️ Platform Email System
RestroAgent's built-in email system sends transactional emails for booking confirmations, order receipts, password resets, and staff invitations. Platform operators configure a shared SMTP account for all outgoing mail and can customise every email template.
SMTP configuration
Navigate to Admin → Email Settings to configure the outgoing mail server:
| Field | Description |
|---|---|
| SMTP Host | Hostname of your mail server (e.g. smtp.sendgrid.net). |
| SMTP Port | Port number — typically 587 for TLS / STARTTLS. |
| Username | SMTP login username (often an API key for providers like SendGrid). |
| Password | SMTP password or API key. |
| From address | The From address shown to email recipients. |
After entering credentials, click Test connection to verify the SMTP settings work before saving.
Email templates
Navigate to Admin → Email Templates to view and customise all transactional email templates:
- Booking confirmation — sent to the customer when a reservation is confirmed.
- Order receipt — sent when an order is placed or completed.
- Welcome email — sent when a new restaurant account is created.
- Password reset — sent when a user requests a password reset link.
- Staff invitation — sent when a restaurant owner invites a new staff member.
Each template has a full HTML editor with variable placeholders (e.g. {{customer_name}},
{{booking_time}}). Changes take effect immediately for all future emails
of that type.
Email delivery log
Navigate to Admin → Email Log to see every email sent by the platform: recipient address, subject, send time, delivery status, and the full rendered HTML body. Use the log to debug missed emails or verify that transactional flows are working correctly.
🎫 Help Desk / Support Tickets
RestroAgent includes a built-in help desk that restaurant owners can use to submit support requests directly to the platform operator without leaving the dashboard. Platform operators manage all tickets from the super-admin panel.
Submitting a ticket (restaurant owner)
- Navigate to Help → Support in the dashboard sidebar.
- Click New ticket.
- Enter a subject, describe the issue in the message body, and select a category (e.g. Billing, Technical, Feature Request) and priority (Low, Medium, High, Urgent).
- Submit. The ticket is created and the support team is notified.
Ticket statuses
| Status | Meaning |
|---|---|
| Open | Ticket submitted and awaiting a response. |
| In Progress | Support team is actively working on the issue. |
| Resolved | Issue fixed or question answered. |
| Closed | Ticket closed by either party. |
Admin response (super-admin panel)
Navigate to Admin → Support to see all open tickets across all tenants, sorted by priority and creation time. Click a ticket to view the full conversation thread, write a reply, and update the status. All replies are visible to the restaurant owner inside their Help → Support view.
Priority levels
- Low — general questions or cosmetic issues; no time pressure.
- Medium — moderate impact; normal queue response time.
- High — significant feature disruption; response prioritised.
- Urgent — platform is down or data loss is occurring; immediate attention required.
🎨 Platform Branding (White-Label Setup)
RestroAgent is designed to be sold as a white-label SaaS product under your own brand. The Platform Branding section lets you replace all RestroAgent visual identity with your own logo, name, and primary colour — without touching any code.
Branding settings
Navigate to Admin → Branding to configure:
- Platform name — the name displayed in the dashboard header, browser tab title, and outgoing emails (e.g. "MyRestaurantOS").
- Logo upload — upload a PNG or SVG logo (recommended size: 200 × 60 px). The logo appears in the dashboard sidebar and on the login page.
-
Primary brand colour — the hex colour code used for buttons, active
sidebar links, and other accent elements throughout the dashboard. Enter as
#rrggbb. - Dynamic favicon — the platform's favicon is served from your branding settings automatically. Upload a square PNG (at least 64 × 64 px) and it appears in the browser tab without any server-side file changes.
Environment variables for branding
| Variable | Effect |
|---|---|
NEXT_PUBLIC_BASE_URL |
Used as the base URL in all outgoing emails (booking confirmations, password resets). Set this to your custom domain so links in emails resolve correctly. |
NEXT_PUBLIC_PLATFORM_NAME |
Fallback platform name used during the initial build before Admin → Branding is configured. Once branding is saved, this env var is superseded by the database value. |
Go-live branding checklist
- Set
NEXT_PUBLIC_BASE_URLto your custom domain in.env. - Rebuild the application:
npm run build && pm2 restart restroagent. - Log in as super-admin and navigate to Admin → Branding.
- Upload your logo (PNG or SVG, 200 × 60 px recommended).
- Upload a square favicon (PNG, at least 64 × 64 px).
- Enter your platform name and primary brand colour.
- Click Save branding. Changes take effect immediately — no rebuild required.
- Hard-refresh the browser (Ctrl+Shift+R / Cmd+Shift+R) to see the updated favicon.
- Send a test booking confirmation email to verify the logo and URL appear correctly.
💳 Razorpay Billing
For markets where Stripe is unavailable or where operators prefer an Indian payment gateway, RestroAgent supports Razorpay as an alternative subscription billing provider. The Razorpay integration mirrors the Stripe billing experience: restaurant owners can subscribe to plans, manage their subscription, and receive webhook-driven status updates.
Setup
-
Create a Razorpay account
Sign up at razorpay.com and complete KYC verification.
-
Obtain API keys
In the Razorpay Dashboard go to Settings → API Keys and generate a key pair. Copy the Key ID and Key Secret.
-
Configure RestroAgent
Navigate to Admin → Billing Settings and select Razorpay as the billing provider. Enter the Key ID and Key Secret.
-
Register the webhook
In the Razorpay Dashboard go to Settings → Webhooks and add a new webhook pointing to:
https://yourdomain.com/api/billing/razorpay-webhook
Enable the following events:
subscription.activated,subscription.charged,subscription.cancelled,subscription.completed. -
Create plans in Razorpay
Create subscription plans in the Razorpay Dashboard with the desired billing amounts and intervals. Copy the Razorpay Plan IDs into the corresponding billing plans in Admin → Billing Plans.
Supported subscription statuses
| Razorpay event | RestroAgent status |
|---|---|
subscription.activated | Active |
subscription.charged | Active (renewed) |
subscription.cancelled | Cancelled |
subscription.completed | Cancelled |
Stripe and Razorpay can coexist in a RestroAgent installation — you can offer both payment gateways to restaurant clients in different regions. Each restaurant's subscription is billed through whichever provider was used at checkout.
Troubleshooting
Application does not start
| Symptom | Likely cause | Fix |
|---|---|---|
| PM2 shows process in errored state | Missing required env var or build not run | Run pm2 logs restroagent — look for the first error line. Ensure npm install && npm run build completed without errors, and all REQUIRED env vars are set in .env. |
Cannot connect to database |
PostgreSQL not running or wrong DATABASE_URL |
Check sudo systemctl status postgresql. Verify DATABASE_URL matches the user/password/dbname created during setup. |
JWT_SECRET is required on boot |
JWT_SECRET not set |
Generate a 64-byte key: node -e "console.log(require('crypto').randomBytes(64).toString('hex'))" and add it to .env. |
Logo / uploaded image does not appear after upload
| Symptom | Likely cause | Fix |
|---|---|---|
Image URL returns 403 or 404 after uploading with STORAGE_DRIVER=s3 |
Bucket is not publicly accessible | Set a public read policy on the bucket (or the uploads/ prefix). See the File Storage section for provider-specific links. Also ensure S3_PUBLIC_URL is set so the app resolves the correct public URL. |
| Image disappears after the next deployment on Render / Railway / Heroku | Platform uses ephemeral filesystem; STORAGE_DRIVER=local is set |
Switch to STORAGE_DRIVER=s3 and configure a persistent S3-compatible bucket. See the File Storage section. |
| Uploaded logo shows in dev but not in production | S3_PUBLIC_URL not set or pointing to the wrong origin |
Set S3_PUBLIC_URL to the public base URL of your bucket or CDN (no trailing slash). Rebuild after changing. |
Database initialisation error on first seed
| Error message | Cause | Fix |
|---|---|---|
relation "users" does not exist |
Schema has not been initialised — seed endpoint not called yet | Call the seed endpoint with your SEED_SECRET: curl -X POST https://yourdomain.com/api/auth/seed-demo-users -H "x-seed-secret: <value>" |
Seed endpoint returns 503 SEED_SECRET is not configured |
SEED_SECRET env var is missing from .env |
Add SEED_SECRET=your-random-secret to .env, rebuild and restart, then retry the seed curl command with the matching header. |
Seed endpoint returns 401 Unauthorized |
The x-seed-secret header value does not match SEED_SECRET |
Confirm the header value exactly matches the SEED_SECRET in your .env file (case-sensitive, no extra spaces). |
password authentication failed for user "restroagent" |
Wrong password in DATABASE_URL |
Re-check the password you set when running CREATE USER restroagent WITH PASSWORD '...' in psql. |
Stripe webhook not triggering subscription updates
| Symptom | Cause | Fix |
|---|---|---|
| Subscription stays in Trial after payment | Webhook not registered or STRIPE_WEBHOOK_SECRET wrong |
In the Stripe Dashboard → Developers → Webhooks, confirm the endpoint URL is https://yourdomain.com/api/billing/stripe-webhook and the signing secret matches STRIPE_WEBHOOK_SECRET in .env. |
| Webhook events show 401 in Stripe delivery logs | Signature verification failing — wrong secret | Copy the Signing secret shown in the Stripe webhook endpoint detail page (not the API key). Update STRIPE_WEBHOOK_SECRET in .env and restart. |
| Stripe events arrive but no DB update | Missing events in webhook subscription | Ensure all four events are enabled on the endpoint: customer.subscription.created, customer.subscription.updated, customer.subscription.deleted, checkout.session.completed. |
Twilio voice calls not connecting
| Symptom | Cause | Fix |
|---|---|---|
| Calls ring but AI never answers / immediately disconnect | WEBHOOK_BASE_URL is not publicly reachable or uses HTTP |
Set WEBHOOK_BASE_URL to your full HTTPS public URL. Twilio cannot reach localhost or plain HTTP. Verify with curl https://yourdomain.com/api/webhooks/twilio/voice. |
| Calls drop mid-conversation or WebSocket closes after 60 s | Nginx proxy_read_timeout too low |
Add or update proxy_read_timeout 86400; inside the location / block in your Nginx config and reload: sudo systemctl reload nginx. |
| Twilio Console shows error 11200 HTTP retrieval failure | The webhook URL returned a non-200 status | Check pm2 logs restroagent for errors at the time of the call. Common causes: missing OPENAI_API_KEY, agent not assigned to the phone number in AI Agent Config. |
| Phone number is not linked to an agent | Twilio phone number purchased but not configured in the dashboard | Go to AI Agent Config → Phone Numbers, link your Twilio number to an AI agent, and set the Twilio webhook URL to https://yourdomain.com/api/webhooks/twilio/voice. |
Next.js dev indicator ("N" button) appearing in production
| Symptom | Cause | Fix |
|---|---|---|
| A floating blue "N" icon or dev toolbar appears in the bottom corner of the browser | The app is running in development mode (NODE_ENV is not production), or the app was started with npm run dev instead of npm start |
Ensure NODE_ENV=production is set in your .env file, then
always start with npm start (or via PM2 running npm start).
Never use npm run dev on a live server. Rebuild after updating env vars:
npm run build && pm2 restart restroagent
|
Indicator still shows after setting NODE_ENV=production |
Old .next/ build was made before the env var was set |
Delete .next/ and rebuild: rm -rf .next && npm run build, then restart PM2. |
Stripe checkout redirects to wrong URL
Set NEXT_PUBLIC_APP_URL to the exact public URL of your app, with
no trailing slash. Rebuild after changing env vars.
Emails not sending
-
Verify SMTP credentials by connecting to your mail server with
telnet SMTP_HOST 587. - Check
SMTP_FROMis authorised to send from your SMTP provider. - Some providers require app passwords — check your email service's documentation.
AI agent gives incorrect or outdated information
- Update menu items and availability in Menu Management.
- Add or update knowledge base entries in Knowledge Base.
- Review the system prompt in AI Agent Config to ensure it reflects current policies.
Build fails with out-of-memory error
Increase the Node.js heap size during build on low-RAM servers.
$ NODE_OPTIONS="--max-old-space-size=1536" npm run build
Support
RestroAgent is developed and maintained by diploy. We are committed to providing excellent after-sales support to all CodeCanyon customers.
For bug reports, configuration help, or feature questions, open a ticket at diploy.ticksy.com. Please include your CodeCanyon purchase code, a description of the issue, and any relevant error messages or screenshots.
What our support covers
- Bug fixes and defects in the original item.
- Help answering questions about included features.
- Guidance on the installation and configuration process described in this documentation.
What our support does not cover
- Customisation or modification requests (available as a paid service — contact us).
- Support for heavily modified versions of the code.
- Third-party service configuration beyond what is described in this documentation (Twilio, Stripe, SMTP).
Useful links
- 🌐 Website: diploy.in
- 🎫 Support: diploy.ticksy.com
Changelog
— Feature Expansion Update
This release documents fifteen additional modules that are present in the codebase and now covered in this documentation for the first time.
New Modules
- Conversations (Omnichannel Inbox) — unified inbox for chat, voice, WhatsApp, email and SMS; human takeover; bulk resolve; call log tab with transcript viewer; CSV export; live polling.
- WhatsApp Integration — Meta WhatsApp Business API; per-branch WABA credentials; webhook at
/api/channels/whatsapp/webhook/[branchId]; 24-hour messaging window handling; template message support with variable substitution; webhook signature verification via App Secret. - QR Storefront — public mobile-first ordering at
/r/[restaurantSlug]/[branchSlug]; live menu browsing; cart, coupon, loyalty and gift-card redemption at checkout; orders appear immediately in the dashboard. - Table Management — per-branch table list; unique QR code per table; printable QR sheet; table linkage to bookings and storefront orders.
- Loyalty Program — tiered point-based loyalty system; configurable earning and redemption rates; tier thresholds (Bronze/Silver/Gold); storefront checkout integration; manual point adjustments from customer profile.
- Gift Cards — issue cards with value and optional expiry; unique code distribution; storefront checkout redemption; full balance ledger per card.
- Coupons & Discounts — flat, percentage and free-item coupon types; minimum order value, per-customer usage limits, total usage caps, expiry date, active/inactive toggle; full usage history.
- Marketing — Audiences & Campaigns — reusable customer segments with live preview count; four quick-start templates; four-step campaign wizard for email and WhatsApp; scheduling, send-rate throttling, delivery statistics and CSV export.
- Multi-Language Support — admin language management; AI-powered bulk translation; RTL auto-layout for Arabic/Hebrew/Farsi; per-user language selector; storefront language inheritance.
- Platform Email System — Admin → Email Settings for SMTP configuration; Admin → Email Templates for customising all transactional email HTML; Admin → Email Log for delivery audit trail.
- Help Desk / Support Tickets — restaurant owners submit tickets with priority and category; admin responds via threaded replies in the super-admin panel; full status lifecycle (Open → In Progress → Resolved → Closed).
- Menu Bulk Upload — CSV-based import/update of categories and items; full column specification; update-vs-create by name matching; pre-import validation with per-row error reporting.
- Platform Branding (White-Label) — Admin → Branding for logo, platform name, primary colour and favicon; dynamic favicon served from database; environment variable guidance; go-live checklist.
- Razorpay Billing — alternative to Stripe for Indian/unsupported-Stripe markets; Admin → Billing Settings credential entry; webhook at
/api/billing/razorpay-webhook; subscription status mapping.
v1.0 — Initial CodeCanyon Release
This is the first public release of RestroAgent. The feature set below was built and refined specifically for the CodeCanyon marketplace.
Core Platform
- Next.js 15 App Router with TypeScript 5 and Tailwind CSS.
- Drizzle ORM with
pgdriver — type-safe database access with parameterised queries. - JWT-based authentication with HttpOnly cookie sessions.
- Role-based access control: superadmin, owner, manager, staff, and custom roles.
- Multi-tenant architecture — full data isolation between restaurants.
- Multi-branch support — isolated orders, bookings, agents and staff per branch.
- AES-256 encryption for sensitive database fields (Twilio credentials, API keys).
- Auto-initialising database schema — no manual migration step required on install.
AI Voice Agent
- Real-time inbound voice calls via Twilio Media Streams WebSocket.
- OpenAI Realtime API for simultaneous speech recognition and synthesis.
- AI tools: create order, check availability, confirm booking, search knowledge base.
- Configurable VAD (Voice Activity Detection) thresholds per agent.
- Human escalation — staff notified and conversation status updated automatically.
- Call log with transcript summary, duration, caller ID and outcome.
- Per-restaurant Twilio credentials encrypted and stored in the database.
AI Chat Widget
- Embeddable widget via a single
<script>tag — no iframe. - Support for any model configured in Admin → LLM Providers (GPT-4o and OpenRouter-routed models).
- Customisable brand colour, greeting message, icon and widget position.
- Staff can take over any chat session from the Conversations dashboard.
- Message template library with multi-language support.
Order Management
- Full order lifecycle: Pending → Confirmed → Kitchen → Ready → Rider → Delivered → Completed.
- Per-restaurant sequential order numbering with format
XXXX-00001. - Real-time order updates without page reload.
- Manual order creation by staff from the dashboard.
- Channel filtering: voice, chat, WhatsApp, email, SMS.
- Order detail drawer with line items, modifiers, customer info and history.
Table Booking Management
- Full booking lifecycle: Pending → Confirmed → Reminder Sent → Seated → Completed / No Show / Cancelled.
- Timeline calendar view across the booking day.
- VIP guest tagging and guest notes (dietary requirements, preferences).
- Automated email reminder system.
- Walk-in and advance reservation support.
Menu Management
- Categories, items, modifier groups and per-modifier pricing.
- Per-item availability toggle (86 items temporarily without deletion).
- Image upload per menu item.
- Drag-and-drop category and item reordering.
- Dietary flags: vegan, vegetarian, gluten-free, nut-free, halal, dairy-free.
Customer CRM
- Unified customer profiles with order history, bookings and conversations.
- Total spend, visit count and first/last seen timestamps.
- Internal staff notes per customer.
- Returning caller recognition (AI references previous orders).
Knowledge Base
- Four entry types: Article, Q&A, Document (PDF/text upload), URL.
- Semantic search retrieval for AI agent context.
- Per-restaurant and per-branch knowledge base entries.
Billing & Subscriptions
- Stripe Subscriptions with monthly/annual billing cycles.
- Admin-managed plans with per-plan feature limits.
- Stripe Billing Portal integration for self-service upgrades, downgrades and cancellations.
- Invoice PDF download.
- 14-day free trial support.
- Webhook-driven status sync: Active, Trial, Past Due, Cancelled.
Super-Admin Panel
- Platform KPI dashboard: restaurants, subscriptions, revenue, conversations, orders.
- Restaurant tenant management: view, suspend, delete, impersonate.
- Billing plan management linked to Stripe products.
- Global AI provider and API key management (OpenAI, OpenRouter, ElevenLabs, Deepgram, Sarvam AI).
- Dashboard language management with AI-powered translation generation.
- White-label branding: platform name, logo and primary colour.
- Immutable audit log for all admin and support actions.
- Support ticket system with priority and status tracking.
- Platform-wide analytics: API usage, LLM consumption, revenue trends.
- Built-in blog / content management for platform landing pages.
Staff & Access Control
- Built-in roles: Owner, Manager, Staff.
- Custom roles with granular per-feature permissions.
- Branch-scoped staff access.
- Staff invitation by email with role pre-assignment.
Alerts & Notifications
- Real-time in-app notifications for orders, bookings, AI escalations, billing and system events.
- Browser audio chime on new order arrival.
- Per-user notification preference settings (in-app and email).
- Platform-wide announcements via super-admin.
REST API & Webhooks
- Restaurant-scoped API key management.
- Outbound webhooks for key events: order created, order status changed, booking created, booking status changed, conversation escalated.
- Webhook delivery log with HTTP response status and body.
- Message template library for AI responses.
Analytics
- Per-restaurant: orders, revenue, average order value, booking volume, AI resolution rate, top items.
- Platform-wide: tenant growth, LLM token usage, subscription revenue.
File Storage
- Configurable storage driver:
local(VPS disk) ors3(S3-compatible cloud storage). - Compatible with AWS S3, DigitalOcean Spaces, Cloudflare R2, MinIO.
- No ACL sent on upload — bucket policy controls public access (compatible with R2 and strict-ACL-free buckets).
S3_PUBLIC_URLfor custom CDN or bucket domain resolution.
Security
withAuthmiddleware on all mutating API routes with role enforcement.- SEED_SECRET production gate on the demo-seed endpoint (required before first-run seed).
- Constant-time secret comparison (crypto.timingSafeEqual) for sensitive header checks.
- AES-256 encrypted storage for Twilio credentials and provider API keys in the database.
- Stripe and Twilio webhook signature verification.
- Zero critical CVEs in the dependency tree at release.