Developer / SDK reference
The embed script, the product-demo SDK, the session/lead API, and webhooks — real endpoints, run against the real server before this page shipped. If something isn't built yet, this page says so.
OVERVIEW
Three real, independent surfaces, and you can use any combination of them:
- Embed script (
/js/embed.js) — a floating launcher that opens a real live demo call with one of your agents, on any page you control. - Product-demo SDK (
/js/product-demo-sdk.js) — install this on your own product so a live Zodiem agent can navigate it: click a real control, highlight a real element, navigate to a real page. - Session & lead API (
/api/v1/*) — a read-only, API-key-authenticated REST API for pulling captured leads and session transcripts into your own systems.
Plus real webhooks (Slack and a generic URL) that fire automatically when a lead is captured — no code required, configured from the dashboard's Integrations tab.
EMBED SCRIPT
Paste this before the closing </body> tag of any page you control. It loads asynchronously (never blocks your page's own render) and renders a floating launcher that opens a real live call with the agent you specify.
<script src="https://your-zodiem-host/js/embed.js" data-agent-id="YOUR_AGENT_ID"></script>
Get your real data-agent-id and the exact snippet (with your real host already filled in) from your dashboard's Agents → your agent → Distribute tab.
| Attribute | Required | Description |
|---|---|---|
data-agent-id | Yes | Which agent the launcher opens a call with. |
STARTING A DEMO
Two real ways to get a visitor into a live demo call today:
- The embed launcher above — the visitor clicks the floating button the script creates.
- A direct link — share
https://your-zodiem-host/?audience=YOUR_AUDIENCE_SLUG(an Audience link, created on the Distribute tab) orhttps://your-zodiem-host/?agentId=YOUR_AGENT_IDdirectly. Both query parameters are read automatically by the widget on any page that loads it, including your own homepage.
Honest gap: there isn't a documented public function yet to open the call from your own custom button instead of the launcher the embed script creates (something like Zodiem.open()). Today, only the script's own launcher and the direct links above start a call. If you need a custom trigger, tell us — it's a reasonable, real request, just not built yet.
WIDGET PARAMETERS
What's actually configurable today — real parameters only, nothing invented:
| Parameter | Where | Type | Required | Description |
|---|---|---|---|---|
data-agent-id | Script attribute | string | Yes | Which agent the embed script's launcher opens. |
agentId | URL query param | string | No | Opens a call with a specific agent when present on the host page's own URL. |
audience | URL query param | string | No | Attributes the session to a named Audience (from the Distribute tab) and can route to a specific agent. |
Honest gap: there's no theme, color, or position option today — the launcher always renders bottom-right with Zodiem's own default styling. A configurable look is not built yet.
PRODUCT-DEMO SDK
Install this on your own product (not your marketing site) so a live Zodiem agent can drive it in real time — click a real button, highlight a real element, navigate to a real page — over postMessage, since your product and the agent's driving context are different origins by design.
<script src="https://your-zodiem-host/js/product-demo-sdk.js" data-agent-id="YOUR_AGENT_ID"></script>
On load, it shows a real, visible banner ("Live AI demo in progress…") so nobody is misled into thinking a human is driving. It fetches a real trust config (/api/public/product-demo-sdk-config) listing which origins are allowed to send it commands, and silently ignores any message from an origin not on that list.
Commands (sent via window.postMessage from an allowed origin):
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Always "zodiem-demo-command". |
commandId | string | Yes | Your own id, echoed back in the acknowledgement. |
action | string | Yes | One of "navigate", "click", "highlight". |
selector | string | For click/highlight | A CSS selector on the page running this SDK. |
path | string | For navigate | A same-origin relative path. A cross-origin URL is refused — this SDK will never navigate your visitor off your own site. |
window.postMessage({
type: "zodiem-demo-command",
commandId: "cmd_1",
action: "highlight",
selector: "#upgrade-button"
}, "https://your-product-origin");
The SDK replies with { type: "zodiem-demo-ack", commandId, ok, error } so the sender knows whether it worked.
SESSION & LEAD API
A read-only REST API for pulling your captured leads and session transcripts into your own systems. Create a key from your dashboard's Settings → API Keys (admin role required); the raw key is shown exactly once, at creation.
| Endpoint | Method | Description |
|---|---|---|
/api/v1/leads | GET | Every lead captured in your workspace. |
/api/v1/sessions | GET | A summary of every session (id, lead email, start/end time, turn count). |
/api/v1/sessions/:id | GET | One session's full real transcript. |
Every request needs an X-API-Key header:
curl https://your-zodiem-host/api/v1/leads \ -H "X-API-Key: zdm_live_your_real_key"
This API is deliberately narrow — exactly the leads and transcripts the pricing page's "Local API access" line promises, not a general-purpose proxy onto every internal route.
WEBHOOKS
Configure a Slack webhook URL or a generic webhook URL from the dashboard's Integrations tab. Both fire automatically, best-effort, the moment a lead is captured — a slow or down webhook never blocks or delays the visitor's call.
The generic webhook POSTs the real lead object as JSON:
POST https://your-endpoint
Content-Type: application/json
{
"id": "...",
"email": "visitor@example.com",
"name": "...",
"companySize": "...",
"createdAt": "2026-01-01T12:00:00.000Z"
}
Delivery retries up to 3 times with real exponential backoff (1s, 2s, 4s) on failure. Every attempt — not just the final outcome — is logged and visible in your dashboard's delivery log.
Honest gap: outgoing webhook payloads are not signed today — there is no HMAC signature header to verify on your end. If your endpoint needs to cryptographically confirm a request really came from Zodiem, that isn't built yet. (Incoming webhooks we receive, from Stripe and ElevenLabs, are HMAC-verified — that's a different, already-real piece of this codebase, just not this direction.)
ERROR HANDLING
Real status codes used consistently across the API above:
| Status | Meaning |
|---|---|
400 | A required field is missing or invalid (e.g. no email on lead capture). |
401 | Missing or invalid X-API-Key, or a revoked key. |
404 | The requested session id doesn't exist in your workspace. |
429 | Your plan's monthly session limit is reached (session-start only) — see the pricing FAQ. |
Every error response is JSON: { "error": "a plain-language message" }.
FULL EXAMPLE
A minimal real page: embed the launcher, and separately pull today's leads with the v1 API.
<!-- Anywhere on your site --> <script src="https://your-zodiem-host/js/embed.js" data-agent-id="YOUR_AGENT_ID"></script>
// A small server-side script, run on your own schedule
const res = await fetch("https://your-zodiem-host/api/v1/leads", {
headers: { "X-API-Key": process.env.ZODIEM_API_KEY },
});
if (!res.ok) {
const { error } = await res.json();
throw new Error(`Zodiem API error: ${error}`);
}
const leads = await res.json();
console.log(`${leads.length} leads captured so far`);
Every snippet on this page was run against a real, running Zodiem server before this page was published.