Skip to content

Quickstart

You will provision a chat tenant, retrieve its three credentials (tenant_id, tenant_secret, widget_public_key), embed the widget on your page, then make a signed backend call to the relay.

Only tenant_name is required; every other field has a default. The response contains tenant_id, tenant_secret and widget_public_key only once.

Fenêtre de terminal
curl $BASE_URL/api/v1/provision/tenant \
-X POST \
-H "X-Admin-Key: YOUR_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"tenant_name": "Demo Boutique",
"allowed_origins": ["https://shop.demo.com", "app://bloonio_chat_flutter"]
}'

Response (201) — the data envelope contains:

{
"status_code": 201,
"data": {
"tenant_id": "019e4ae7-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"tenant_secret": "sk_...",
"widget_public_key": "pk_...",
"tenant_name": "Demo Boutique",
"rate_limit_per_min": 60,
"created_at": "2026-06-21T10:00:00Z"
},
"message": "Tenant provisioned. Save tenant_secret and widget_public_key now — the secret will not be shown again."
}

Store the values where they are used — two distinct surfaces:

Fenêtre de terminal
# Tenant backend (HMAC#1, e.g. your service's .env.*)
CHAT_RELAY_BASE_URL=$BASE_URL
CHAT_RELAY_TENANT_ID=019e4ae7-1a2b-7c3d-8e4f-5a6b7c8d9e0f
CHAT_RELAY_TENANT_SECRET=sk_... # SECRET — never commit
# Widget / in-app SDK (public .env — the widget key is not secret)
CHAT_TENANT_ID=019e4ae7-1a2b-7c3d-8e4f-5a6b7c8d9e0f
CHAT_WIDGET_PUBLIC_KEY=pk_...

The widget_public_key is not a secret: it pairs with the tenant_id to route widget traffic and verify allowed_origins. The tenant_secret, however, signs your backend calls — keep it server-side.

With @bloonio/chat-angular, declare the provider then drop the launcher anywhere. Full details on Widget & SDK.

app.config.ts
import { provideBloonioChat } from '@bloonio/chat-angular';
export const appConfig = {
providers: [
provideBloonioChat({
tenantId: '019e4ae7-1a2b-7c3d-8e4f-5a6b7c8d9e0f',
publicKey: 'pk_...',
baseUrl: '$BASE_URL',
locale: 'en',
}),
],
};
// a standalone component
import { BloonioChatLauncherComponent } from '@bloonio/chat-angular';
@Component({
standalone: true,
imports: [BloonioChatLauncherComponent],
template: `<router-outlet /> <bloonio-chat-launcher />`,
})
export class AppComponent {}

Your page’s origin must be listed in allowed_origins, otherwise the relay refuses to create the visitor session (403).

Backend → relay calls (/api/v1/relay/*) are signed with HMAC#1. The Python SDK signs for you; here is the example of minting an operator token, where your backend delegates its identity to the relay.

from bloonio_chat_relay_client import get_chat_client
chat = get_chat_client() # reads BLOONIO_CHAT_* from the environment
convo = chat.create_conversation(
visitor_user_id="user-123",
visitor_display_name="Mary",
locale="en",
)
chat.send_message(convo.id, role="visitor", content="Where is my order?")
  1. You provisioned a tenant with the admin key and captured its three credentials (shown only once).
  2. The widget authenticates with the relay using the widget_public_key + the tenant_id, and creates a visitor session if the origin is allowed.
  3. Your backend signs its calls with HMAC#1 using the tenant_secret; the relay verifies the signature, the time window and the tenant status before routing to bloonio_chat_api.