Admin dashboard · API · Live chat
Upuah
One control panel. Your API. Live conversations.
Invite employees to your workspace, chat with visitors from the dashboard, automate replies, and brand the widget — AI soon.
- 1 Install
- 2 Conversation
- 3 Dashboard
- 1Install the Upuah plugin on WordPress
- 2Activate it from the Plugins page
- 3Paste your API key — done
Same widget, same inbox.
Conversation coming from WhatsApp Conversation coming from web chat
- Ahmed And do you support WhatsApp? 2m
- Visitor #4812 How long is the setup? 5m
- Ticket #128 The invoice never arrived 12m
In short
We build the control panel. You connect the API and run chat.
One sentence for the whole product: Upuah ships the admin layer — your team connects keys, answers live, and automates replies. AI is soon.
emb_8k2m…
Connected
How Upuah works
From dashboard setup to live conversations.
Connect keys, brand the widget, staff the inbox, and automate first responses — all from admin.
Connect your workspace
Create API keys in the admin dashboard and attach Upuah to your product surfaces.
- Publishable + secret keys
- Allowed domains locked
Operate live chat
Your team replies from the inbox while visitors chat on your branded widget.
- Shared agent inbox
- Realtime visitor chat
Automate & brand
Set automatic replies, themes, and launcher rules — AI replies coming soon.
- Auto-reply rules
- Widget theme · AI Soon
Team chat
Where your team works — live, automated, and connected.
Mock screens from the agent side of Upuah — how your team sees and answers conversations.
Brand control
Centralized design. Consistent delivery.
Marketing and support teams shape the chat experience in the dashboard. Engineering deploys it with keys — without rebuilding the UI for every site.
Customer-facing preview
Credentials
API keys built for clear separation of risk.
Issue keys from the dashboard with roles your security team expects — publishable for the client, secret for the backend.
Intended for client-side initialization. Restricted to approved origins and channels.
Safe to paste into your page. It can only open a chat with you — it cannot read anything.
emb_8k2mq9xl4nr7vp0a91fj3wd6ts5ub7yc4ke2nh8x
Full access for sessions, messaging, and webhooks. Remains on your infrastructure only.
Never put this in a page. It reads and writes every conversation, ticket, and setting in your workspace.
upuah_••••••••••••••••c3e2
Reliability
Infrastructure shaped by a decade of live traffic.
Upuah is operated as long-running production infrastructure — monitored, versioned, and documented for teams that cannot afford guesswork.
- Since 2014
- Serving branded chat experiences across consumer and B2B sites.
- 99.99%
- Uptime objective with status history and incident communication.
- Global edge
- Low-latency delivery for visitors and agent workspaces worldwide.
- Stable API
- Versioned endpoints and clear deprecation windows for enterprise change control.
Platform
Built for how real teams run chat.
Not a stacked feature list — four pillars of the Upuah control panel, designed to ship and operate together.
Admin control panel
Connect the API, invite agents, and run every property from one governed workspace.
Automatic replies
Admins register greetings, after-hours messages, and keyword triggers — no deploy required.
Team live inbox
Agents answer in real time while visitors use your branded on-site widget.
AI replies Soon
Suggested and automated AI responses land in the same dashboard — roadmap, not vaporware UI.
Integrate
Connect in the stack you already ship.
Embed from the browser, call the API from your backend, ship in mobile apps, or install on WordPress and Shopify — web, server, React Native, Flutter, Expo, Swift, Kotlin, Ionic, and more.
<script src="https://cdn.upuah.com/widget.js" defer></script>
<script>
window.Upuah = window.Upuah || [];
Upuah.push(['init', {
key: 'emb_8k2mq9xl4nr7vp0a91fj3wd6ts5ub7yc4ke2nh8x',
channel: 'support'
}]);
</script>
import { useEffect } from 'react';
export function UpuahChat() {
useEffect(() => {
const s = document.createElement('script');
s.src = 'https://cdn.upuah.com/widget.js';
s.async = true;
document.body.appendChild(s);
window.Upuah = window.Upuah || [];
Upuah.push(['init', {
key: 'emb_8k2mq9xl4nr7vp0a91fj3wd6ts5ub7yc4ke2nh8x',
channel: 'support'
}]);
}, []);
return null;
}
<script setup>
import { onMounted } from 'vue'
onMounted(() => {
const s = document.createElement('script')
s.src = 'https://cdn.upuah.com/widget.js'
s.defer = true
document.body.appendChild(s)
window.Upuah = window.Upuah || []
Upuah.push(['init', {
key: 'emb_8k2mq9xl4nr7vp0a91fj3wd6ts5ub7yc4ke2nh8x',
channel: 'support'
}])
})
</script>
// app/layout.tsx or _app.tsx
import Script from 'next/script';
export default function RootLayout({ children }) {
return (
<html>
<body>
{children}
<Script src="https://cdn.upuah.com/widget.js" strategy="afterInteractive" />
<Script id="Upuah-init">{`
window.Upuah = window.Upuah || [];
Upuah.push(['init', {
key: 'emb_8k2mq9xl4nr7vp0a91fj3wd6ts5ub7yc4ke2nh8x',
channel: 'support'
}]);
`}</Script>
</body>
</html>
);
}
// plugins/upuah.client.ts
export default defineNuxtPlugin(() => {
const s = document.createElement('script')
s.src = 'https://cdn.upuah.com/widget.js'
s.defer = true
document.body.appendChild(s)
window.Upuah = window.Upuah || []
Upuah.push(['init', {
key: 'emb_8k2mq9xl4nr7vp0a91fj3wd6ts5ub7yc4ke2nh8x',
channel: 'support'
}])
})
import { Component, OnInit } from '@angular/core';
@Component({
selector: 'app-upuah',
template: ''
})
export class UpuahComponent implements OnInit {
ngOnInit() {
const s = document.createElement('script');
s.src = 'https://cdn.upuah.com/widget.js';
s.async = true;
document.body.appendChild(s);
(window as any).Upuah = window.Upuah || [];
Upuah.push(['init', {
key: 'emb_8k2mq9xl4nr7vp0a91fj3wd6ts5ub7yc4ke2nh8x',
channel: 'support'
}]);
}
}
import fetch from 'node-fetch';
const res = await fetch('https://api.upuah.com/v1/messages', {
method: 'POST',
headers: {
'Authorization': 'Bearer upuah_••••••••c3e2',
'Content-Type': 'application/json'
},
body: JSON.stringify({
channel: 'support',
text: 'Thanks — an agent will reply shortly.'
})
});
const data = await res.json();
import express from 'express';
const app = express();
app.post('/webhook/upuah', express.json(), async (req, res) => {
const reply = await fetch('https://api.upuah.com/v1/messages', {
method: 'POST',
headers: {
'Authorization': 'Bearer upuah_••••••••c3e2',
'Content-Type': 'application/json'
},
body: JSON.stringify({
channel: 'support',
text: 'Thanks — an agent will reply shortly.'
})
});
res.json(await reply.json());
});
import requests
res = requests.post(
"https://api.upuah.com/v1/messages",
headers={
"Authorization": "Bearer upuah_••••••••c3e2",
"Content-Type": "application/json",
},
json={
"channel": "support",
"text": "Thanks — an agent will reply shortly.",
},
)
data = res.json()
import requests
from django.http import JsonResponse
from django.views.decorators.http import require_POST
@require_POST
def upuah_reply(request):
res = requests.post(
"https://api.upuah.com/v1/messages",
headers={
"Authorization": "Bearer upuah_••••••••c3e2",
"Content-Type": "application/json",
},
json={
"channel": "support",
"text": "Thanks — an agent will reply shortly.",
},
)
return JsonResponse(res.json())
from fastapi import FastAPI
import httpx
app = FastAPI()
@app.post("/upuah/reply")
async def upuah_reply():
async with httpx.AsyncClient() as client:
res = await client.post(
"https://api.upuah.com/v1/messages",
headers={
"Authorization": "Bearer upuah_••••••••c3e2",
},
json={
"channel": "support",
"text": "Thanks — an agent will reply shortly.",
},
)
return res.json()
<?php
$ch = curl_init('https://api.upuah.com/v1/messages');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer upuah_••••••••c3e2',
'Content-Type: application/json',
],
CURLOPT_POSTFIELDS => json_encode([
'channel' => 'support',
'text' => 'Thanks — an agent will reply shortly.',
]),
CURLOPT_RETURNTRANSFER => true,
]);
$data = json_decode(curl_exec($ch), true);
use Illuminate\Support\Facades\Http;
$response = Http::withToken('upuah_••••••••c3e2')
->post('https://api.upuah.com/v1/messages', [
'channel' => 'support',
'text' => 'Thanks — an agent will reply shortly.',
]);
$data = $response->json();
package main
import (
"bytes"
"net/http"
)
func main() {
body := []byte(`{"channel":"support","text":"Thanks — an agent will reply shortly."}`)
req, _ := http.NewRequest("POST", "https://api.upuah.com/v1/messages", bytes.NewBuffer(body))
req.Header.Set("Authorization", "Bearer upuah_••••••••c3e2")
req.Header.Set("Content-Type", "application/json")
http.DefaultClient.Do(req)
}
import { useEffect, useState } from 'react';
import { View, TextInput, Button, FlatList, Text } from 'react-native';
const UPUAH_KEY = 'emb_8k2mq9xl4nr7vp0a91fj3wd6ts5ub7yc4ke2nh8x';
export default function UpuahChat() {
const [messages, setMessages] = useState([]);
const [text, setText] = useState('');
async function send() {
const res = await fetch('https://api.upuah.com/v1/messages', {
method: 'POST',
headers: {
'Authorization': `Bearer ${UPUAH_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ channel: 'support', text })
});
const data = await res.json();
setMessages((prev) => [...prev, data]);
setText('');
}
return (
<View>
<FlatList data={messages} renderItem={({ item }) => <Text>{item.text}</Text>} />
<TextInput value={text} onChangeText={setText} />
<Button title="Send" onPress={send} />
</View>
);
}
import 'package:http/http.dart' as http;
import 'dart:convert';
const upuahKey = 'emb_8k2mq9xl4nr7vp0a91fj3wd6ts5ub7yc4ke2nh8x';
Future<Map<String, dynamic>> sendUpuahMessage(String text) async {
final res = await http.post(
Uri.parse('https://api.upuah.com/v1/messages'),
headers: {
'Authorization': 'Bearer $upuahKey',
'Content-Type': 'application/json',
},
body: jsonEncode({
'channel': 'support',
'text': text,
}),
);
return jsonDecode(res.body) as Map<String, dynamic>;
}
// Use inside a StatefulWidget TextField + ElevatedButton
// await sendUpuahMessage(controller.text);
import { useState } from 'react';
import { View, TextInput, Pressable, Text } from 'react-native';
const UPUAH_KEY = 'emb_8k2mq9xl4nr7vp0a91fj3wd6ts5ub7yc4ke2nh8x';
export default function SupportScreen() {
const [text, setText] = useState('');
const [status, setStatus] = useState('');
async function sendMessage() {
const res = await fetch('https://api.upuah.com/v1/messages', {
method: 'POST',
headers: {
'Authorization': `Bearer ${UPUAH_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
channel: 'support',
text,
meta: { platform: 'expo' }
})
});
setStatus(res.ok ? 'Sent' : 'Failed');
setText('');
}
return (
<View style={{ padding: 16 }}>
<TextInput value={text} onChangeText={setText} placeholder="Message support" />
<Pressable onPress={sendMessage}>
<Text>Send via Upuah</Text>
</Pressable>
<Text>{status}</Text>
</View>
);
}
import Foundation
let upuahKey = "emb_8k2mq9xl4nr7vp0a91fj3wd6ts5ub7yc4ke2nh8x"
func sendUpuahMessage(_ text: String) async throws -> [String: Any] {
var request = URLRequest(url: URL(string: "https://api.upuah.com/v1/messages")!)
request.httpMethod = "POST"
request.setValue("Bearer \(upuahKey)", forHTTPHeaderField: "Authorization")
request.setValue("application/json", forHTTPHeaderField: "Content-Type")
request.httpBody = try JSONSerialization.data(withJSONObject: [
"channel": "support",
"text": text,
"meta": ["platform": "ios"]
])
let (data, _) = try await URLSession.shared.data(for: request)
return try JSONSerialization.jsonObject(with: data) as? [String: Any] ?? [:]
}
// Task { try await sendUpuahMessage("Need help with my order") }
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.RequestBody.Companion.toRequestBody
val upuahKey = "emb_8k2mq9xl4nr7vp0a91fj3wd6ts5ub7yc4ke2nh8x"
val client = OkHttpClient()
fun sendUpuahMessage(text: String): String {
val json = """{"channel":"support","text":"$text","meta":{"platform":"android"}}"""
val body = json.toRequestBody("application/json".toMediaType())
val request = Request.Builder()
.url("https://api.upuah.com/v1/messages")
.addHeader("Authorization", "Bearer $upuahKey")
.post(body)
.build()
client.newCall(request).execute().use { response ->
return response.body?.string().orEmpty()
}
}
import { Component } from '@angular/core';
import { HttpClient, HttpHeaders } from '@angular/common/http';
@Component({
selector: 'app-upuah-chat',
template: `
<ion-input [(ngModel)]="text" placeholder="Message"></ion-input>
<ion-button (click)="send()">Send</ion-button>
`
})
export class UpuahChatComponent {
text = '';
private key = 'emb_8k2mq9xl4nr7vp0a91fj3wd6ts5ub7yc4ke2nh8x';
constructor(private http: HttpClient) {}
send() {
const headers = new HttpHeaders({
'Authorization': `Bearer ${this.key}`,
'Content-Type': 'application/json'
});
this.http.post('https://api.upuah.com/v1/messages', {
channel: 'support',
text: this.text,
meta: { platform: 'ionic' }
}, { headers }).subscribe();
}
}
Full WordPress plugin setup steps are in the documentation. Download the Upuah plugin ZIP from the docs, then upload and activate it in WordPress (Plugins → Add New → Upload Plugin).
Open documentation# 1. Download upuah.zip from Documentation
# 2. WP Admin → Plugins → Add New → Upload Plugin
# 3. Activate “Upuah Live Chat”
# 4. Settings → Upuah → paste your publishable key
define('UPUAH_PUB_KEY', 'emb_8k2mq9xl4nr7vp0a91fj3wd6ts5ub7yc4ke2nh8x');
define('UPUAH_CHANNEL', 'support');
Add Upuah in Online Store → Themes → Edit code, or install the Upuah Shopify app when it ships. Paste your publishable key in theme settings.
Open documentation{% comment %} layout/theme.liquid — before </body> {% endcomment %}
<script src="https://cdn.upuah.com/widget.js" defer></script>
<script>
window.Upuah = window.Upuah || [];
Upuah.push(['init', {
key: 'emb_8k2mq9xl4nr7vp0a91fj3wd6ts5ub7yc4ke2nh8x',
channel: 'support',
meta: {
shop: {{ shop.permanent_domain | json }},
customer: {{ customer.id | default: blank | json }}
}
}]);
</script>
Pricing
Simple plans for teams that outgrow basic widgets.
Every plan includes the admin dashboard, API keys, live inbox, and automatic replies. AI is marked soon across all tiers.
Starter
EGP 100/mo
For early teams embedding chat on a single site.
- 1 month — list price
- 12 months — 5% off (EGP 95/mo)
- 1 workspace · 2 agents
- Live inbox
- Automatic replies
- Publishable & secret keys
- Widget branding
- AI replies Soon
- WhatsApp channel · 1 number
Most chosen
Growth
EGP 149/mo
For product and support teams running multiple properties.
- 1 month — list price
- 12 months — 10% off (EGP 134.1/mo)
- 24 months — 20% off (EGP 119.2/mo)
- 5 workspaces · 15 agents
- Live inbox + presence
- Unlimited auto-reply rules
- Webhooks & channels
- Priority email support
- AI replies Soon
- WhatsApp channel · 10 numbers
Enterprise
Custom
For organizations that need governance, scale, and dedicated support.
- 12 months — list price
- 24 months — list price
- Unlimited agents & sites
- SSO / security review
- Dedicated uptime objectives
- Custom limits & contracts
- Solution engineering
- AI roadmap alignment Soon
- WhatsApp channel · unlimited numbers
Get started