Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.usetitan.app/llms.txt

Use this file to discover all available pages before exploring further.

The Connect Widget is a hosted, embeddable UI that handles the entire WhatsApp connection flow on your behalf. Your backend creates a short-lived widget session, your frontend embeds the resulting URL, and the user completes the flow — scanning a QR code, entering a pairing code, or clicking through Meta Embedded Signup — all inside the same widget. When the connection succeeds, Titan notifies your app via a postMessage event or a redirect callback.

Widget modes

The widget supports four modes. Choose based on the connection methods you want to offer:
ModeTabs shownBest for
allQR + Pairing + Cloud APILetting the user choose their preferred method
qrQR code onlyMulti-device linking via scan
pairingPhone number code onlyUsers without a camera or on desktop
cloud-apiMeta Embedded Signup onlyConnecting numbers via the official Cloud API

Integration

Step 1 — Create a widget session (backend)

Call POST /api/widget/sessions from your server using your API key. Never expose your API key to the browser.
curl -X POST https://api.titanapp.dev/api/widget/sessions \
  -H "Authorization: Bearer $API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "mode": "all",
    "callbackUrl": "https://myapp.com/whatsapp/callback"
  }'
Response (201):
{
  "success": true,
  "data": {
    "widgetUrl": "https://api.titanapp.dev/widget/connect?token=eyJ...",
    "widgetToken": "eyJ...",
    "session": "widget-lz1abc-x9f2"
  }
}
Save the session value — it’s the name you’ll use to send messages once the user connects. The widgetUrl is the URL to embed.

Step 2 — Embed the widget (frontend)

Pass the widgetUrl from your server to your frontend and embed it using one of three options:
The simplest option. The loader creates an iframe automatically from the data-widget-url attribute.
<script
  src="https://api.titanapp.dev/widget/embed.js"
  data-widget-url="{{widgetUrl}}">
</script>

Step 3 — Listen for the connection event

When the user successfully connects, the widget posts a message to the parent window. Listen for it:
window.addEventListener('message', (event) => {
  if (event.data?.type === 'titan:widget') {
    if (event.data.event === 'connected') {
      console.log('WhatsApp connected!');
      console.log('Session:', event.data.session);
      console.log('Method:', event.data.method); // "qr" | "pairing" | "cloud-api"

      // If connected via Meta Cloud API, event.data.meta contains WABA details
      if (event.data.meta) {
        console.log('WABA ID:', event.data.meta.wabaId);
        console.log('Phone sessions:', event.data.meta.sessions);
      }
    }
  }
});

Redirect callback

If you prefer a server-side callback over postMessage, pass a callbackUrl when creating the widget session. After the user connects, the widget redirects them to:
https://myapp.com/whatsapp/callback?session=widget-lz1abc-x9f2&status=connected&method=qr
Query parameters:
ParameterValue
sessionThe session name from the widget session response
statusconnected on success
methodqr, pairing, or cloud-api

Custom session name

By default Titan generates a random session name like widget-lz1abc-x9f2. To use your own naming convention, pass sessionName:
{
  "mode": "qr",
  "sessionName": "user-12345",
  "callbackUrl": "https://myapp.com/callback"
}
Session names must follow the standard naming rules: alphanumeric, dots, hyphens, and underscores, 1–64 characters.

BYOA — Bring Your Own Meta App

If you are a platform building on top of Titan and your customers have their own Meta Apps, you can pass their credentials so the Meta Embedded Signup popup shows their branding instead of yours:
{
  "mode": "cloud-api",
  "metaApp": {
    "appId": "CUSTOMER_META_APP_ID",
    "appSecret": "CUSTOMER_META_APP_SECRET"
  }
}
BYOA requires your customer to be at least an Independent Tech Provider with Meta and to have the WhatsApp product with Embedded Signup enabled on their Meta App.

Security

Widget tokens are designed to be safely embedded in iframe URLs:
  • Short-lived — tokens expire after 15 minutes
  • Scoped — each token is bound to a single session and tenant
  • HMAC-signed — tampering is detected before the widget page loads; a tampered or expired token returns 403
  • Not your API key — the widget token has no ability to call other API endpoints
Generate a fresh widget session for each user flow. Do not reuse tokens across users or sessions.

Troubleshooting

IssueLikely causeFix
”Missing widget token”No ?token= in the URLUse the full widgetUrl from the API response, not just the base URL
”Invalid widget token”Token expired (>15 min) or tamperedCreate a new widget session and embed the new URL
QR code never appearsSession failed to startCheck that the session was created successfully and your API key has sessions:manage scope
Meta signup tab missingMETA_APP_ID not configured, or mode is not cloud-api or allUse mode: "cloud-api" and ensure your account has Cloud API enabled, or pass metaApp for BYOA
postMessage not receivedChecking wrong event propertiesThe widget posts to *; verify your listener checks event.data.type === 'titan:widget'