Embed
Drop a chat widget backed by one of your deployed flows into your own site — a publishable key, a <script> tag or a React component, no platform secret in the browser.
Create a widget config
A widget config names one flow and the origins a browser may call it from. Unlike a tenant API key, the publishable key it mints back is not a secret — it is designed to be embedded in client-side JS, so it is returned on every read, not shown once.
curl -X POST https://api.swifttune.ai/api/v1/tenants/TENANT_ID/widget-configs \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"flowId": "FLOW_ID",
"name": "Support widget",
"allowedOrigins": ["https://your-site.example"]
}'Save data.publishableKey from the response. It travels with the flow: your next deploy bakes the current config into the deployment automatically, and every request from an origin not in allowedOrigins is refused before the flow ever runs.
<script> tag
The @swifttune/sdk package ships an auto-mounting build for a plain HTML page — no bundler required. Every option beyond the two credentials is optional.
<script
src="https://unpkg.com/@swifttune/sdk/dist/embed.global.js"
data-publishable-key="pk_live_…"
data-worker-url="https://st-….workers.dev"
data-title="Support"
defer
></script>React
The same widget as a drop-in component, from the @swifttune/sdk/react subpath so a bundler that never loads the script build never pulls React in for a page that does not use it.
import { ChatWidget } from '@swifttune/sdk/react';
<ChatWidget
publishableKey="pk_live_…"
workerUrl="https://st-….workers.dev"
title="Support"
/>Theming
The widget reads the same --st-color-* custom properties the SwiftTune product itself is styled with. A host page that already sets them on :root is picked up automatically; one that does not can pass a theme prop (React) or data-theme-color-* attributes (script tag) to override individual tokens.