{ } Developer Platform

Build with the Embott API.
REST. Webhooks. SDKs.

Everything you'd expect from a modern AI platform — OpenAPI 3.1 spec, signed webhooks, idiomatic SDKs in 4 languages, and a sandbox that's free to use.

One platform, three building blocks.

Whether you're stitching Embott into an existing product or building a custom integration on top, you only need to know three primitives.

🔌

REST API

Fully documented OpenAPI 3.1 spec. Send messages, manage bots, query conversations, push leads. Token-auth, predictable JSON. Rate limited 600 req/min by default.

Reference →
🔔

Webhooks

14 event types. HMAC-SHA256 signed payloads. Auto-retry with exponential backoff up to 24h. View deliveries and replay in the dashboard.

Subscribe →
📦

SDKs

Official clients for JavaScript/TypeScript, Python, PHP, and Ruby. Each wraps the REST API + webhook signature verification. Maintained in lockstep with the API.

Install →

REST API

Base URL: https://api.embott.com/v1. All requests require Authorization: Bearer <your_api_key>.

# Send a message to an Embott conversation
curl https://api.embott.com/v1/conversations/conv_abc123/messages \
  -H "Authorization: Bearer $EMBOTT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "role": "user",
    "content": "Do you ship internationally?"
  }'
import { Embott } from "embott";

const client = new Embott({ apiKey: process.env.EMBOTT_API_KEY });

const reply = await client.conversations.sendMessage({
  conversationId: "conv_abc123",
  role: "user",
  content: "Do you ship internationally?",
});

console.log(reply.message.content);
from embott import Embott

client = Embott(api_key=os.environ["EMBOTT_API_KEY"])

reply = client.conversations.send_message(
    conversation_id="conv_abc123",
    role="user",
    content="Do you ship internationally?",
)

print(reply.message.content)
<?php
use Embott\Client;

$client = new Client(getenv('EMBOTT_API_KEY'));

$reply = $client->conversations->sendMessage([
    'conversation_id' => 'conv_abc123',
    'role'            => 'user',
    'content'         => 'Do you ship internationally?',
]);

echo $reply->message->content;

Resources

MethodEndpointPurpose
GET/v1/botsList all bots in your account
POST/v1/botsCreate a new bot
GET/v1/bots/:idGet bot details + config
PUT/v1/bots/:idUpdate bot config or persona
GET/v1/conversationsList conversations, filter by bot/date/status
GET/v1/conversations/:idFull transcript with metadata
POST/v1/conversations/:id/messagesSend a message to a conversation
POST/v1/conversations/:id/handoffEscalate to a human + notify team
GET/v1/leadsCaptured leads with attribution
POST/v1/leads/:id/exportPush to CRM (HubSpot, Salesforce…)
GET/v1/productsSynced product catalog
POST/v1/products/syncTrigger an immediate re-crawl
GET/v1/analytics/overviewAggregated KPIs by date range
POST/v1/webhooksSubscribe to events
DEL/v1/webhooks/:idUnsubscribe

Webhooks

Subscribe once, get notified on every important event. Payloads are JSON, signed with HMAC-SHA256 using your endpoint secret. Embott auto-retries failed deliveries 9 times over 24 hours.

conversation.started

A new visitor opened a chat session.

conversation.ended

Session closed by visitor or auto-timeout.

message.created

Any new message — visitor, bot, or agent.

lead.captured

Visitor shared contact info (name/email/phone).

lead.qualified

Bot marked the lead as a hot prospect.

handoff.requested

Visitor or bot asked for a human agent.

handoff.accepted

An agent claimed the handoff.

order.attributed

Order linked to a chat (Shopify/Woo).

cart.recovered

Bot recovered an abandoned cart.

booking.created

Bot booked a meeting via Calendly/Cal.com.

integration.connected

A new integration was authorized.

integration.disconnected

An integration revoked or expired.

bot.deployed

Bot configuration published to production.

bot.error

Bot hit a fatal error in a conversation.

Verifying signatures (Node.js)

import crypto from "node:crypto";

function verify(rawBody, header, secret) {
  const [t, sig] = header.split(",").map(p => p.split("=")[1]);
  const expected = crypto.createHmac("sha256", secret)
    .update(`${t}.${rawBody}`)
    .digest("hex");
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(sig));
}

Official SDKs

Type-safe, idiomatic, and maintained in lockstep with the REST API. Each SDK ships with retry, pagination, and webhook signature helpers built in.

Authentication

Two-tier credentials. Public test keys (pk_test_*) for sandbox. Secret live keys (sk_live_*) for production. Rotate any time without redeploying.

ScopeGranted byUse case
bots:readDefault on all keysList + inspect bot configs
bots:writeWorkspace adminCreate, update, deploy bots
conversations:readDefaultRead transcripts and metadata
conversations:writeWorkspace adminSend messages, trigger handoffs
leads:readDefaultQuery captured leads
leads:exportWorkspace adminPush leads to CRMs
webhooks:manageWorkspace adminSubscribe and unsubscribe

Ship a custom module in an afternoon.

Get a sandbox key, hit the API, ship to your customers. Free up to 1,000 calls/day forever.

Get an API key Talk to a dev