Documentation Index
Fetch the complete documentation index at: https://docs.whatabot.app/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The embedded flow editor uses a 3-step authentication flow that keeps your client secret secure on your backend while giving the iframe short-lived access tokens.
Prerequisite: Create an OAuth Client
Before starting the integration, you need to create an OAuth Client linked to the workspace that will be embedded.
- Go to the whatabot Dashboard
- Navigate to the Workspaces screen
- Click Edit on the desired workspace
- Go to the Embed tab
- Click Create Client and copy the
clientId and clientSecret
Store the clientSecret in a secure location. It is only shown once and
should be stored only on your backend.
Authentication flow
┌─────────────┐ ┌──────────────┐ ┌──────────────┐
│ Your App │ │ Your Backend│ │ whatabot API│
│ (Frontend) │ │ │ │ │
└──────┬───────┘ └──────┬───────┘ └──────┬───────┘
│ │ │
│ 1. Request OTT │ │
│───────────────────>│ │
│ │ 2. POST /auth/ │
│ │ iframe-token │
│ │ (Basic Auth) │
│ │───────────────────>│
│ │ │
│ │ 3. Returns OTT │
│ │<───────────────────│
│ │ │
│ 4. Return OTT │ │
│<───────────────────│ │
│ │ │
│ 5. POST /auth/exchange (ott) │
│────────────────────────────────────────>│
│ │ │
│ 6. access_token + refresh_token │
│<────────────────────────────────────────│
│ │ │
│ 7. API calls with access_token │
│────────────────────────────────────────>│
Step 1: Get a one-time token (OTT)
Your backend calls the whatabot API with Basic Auth using the client credentials. This returns a one-time token that is valid for 60 seconds.
curl -X POST https://api.whatabot.app/api/auth/iframe-token \
-H "Authorization: Basic $(echo -n 'clientId:clientSecret' | base64)" \
-H "Content-Type: application/json"
Response:
{
"ott": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
The OTT expires after 60 seconds. Your frontend must exchange it before it
expires. Each OTT can only be used once.
Why use a one-time token?
The OTT pattern ensures that the clientSecret is never exposed in frontend code. Your backend holds the secret and generates short-lived, single-use tokens that the frontend can safely pass to the iframe.
Integration example
Here is a complete example showing how to integrate the embedded editor into a web application:
Backend (Node.js)
// Your backend endpoint that the frontend calls to get an OTT
app.post("/api/whatabot/ott", async (req, res) => {
const clientId = process.env.WHATABOT_CLIENT_ID;
const clientSecret = process.env.WHATABOT_CLIENT_SECRET;
const credentials = Buffer.from(`${clientId}:${clientSecret}`).toString(
"base64",
);
const response = await fetch(
"https://api.whatabot.app/api/auth/iframe-token",
{
method: "POST",
headers: {
Authorization: `Basic ${credentials}`,
"Content-Type": "application/json",
},
},
);
const { ott } = await response.json();
res.json({ ott });
});
Frontend (HTML/JavaScript)
<script>
const FLOW_ID = "019cfebf-b789-794b-9a86-3098d6e82772"; // your flow UUID
const LANG = "en"; // "en" or "pt"
const THEME = "light"; // "light" or "dark"
const BASE_URL = "https://flow.whatabot.app";
async function initEditor() {
// 1. Get OTT from your backend
const response = await fetch("/api/whatabot/ott", { method: "POST" });
const { ott } = await response.json();
// 2. Set iframe src with flow URL
const iframe = document.getElementById("whatabot-editor");
iframe.src = `${BASE_URL}/${LANG}/flows/builder/${FLOW_ID}?theme=${THEME}`;
// 3. Pass OTT to the iframe via postMessage
iframe.addEventListener("load", () => {
iframe.contentWindow.postMessage({ type: "auth", ott }, BASE_URL);
});
}
initEditor();
</script>
<iframe
id="whatabot-editor"
style="width: 100%; height: 600px; border: none;"
></iframe>