Developers

API Reference

A simple REST API to read your CRM and conversations, inject messages from any source, pull metrics, and draft AI replies from your knowledge base. JSON in, JSON out.

OpenAPI 3.1 spec — import into Postman / Insomnia →

Authentication

Every request is authenticated with your workspace API key as a Bearer token. Find it in Dashboard → Contacts → Connect your app. Keep it secret — it grants full access to your workspace data.

Authorization: Bearer od_sk_your_workspace_key
Content-Type: application/json

Base URL:  https://onebubbles.com/api/v1

JavaScript SDK

A tiny wrapper for the browser and Node 18+. Or just call the REST endpoints below directly.

<script src="https://onebubbles.com/onebubbles.js"></script>
<script>
  const ob = Onebubbles.createClient("od_sk_...");

  await ob.contacts.upsert({ email: "jane@acme.com", name: "Jane" });
  await ob.messages.send({ externalId: "u-1", message: "Hi there" });
  const { conversations } = await ob.conversations.list({ email: "jane@acme.com" });
  const { reply } = await ob.ai.reply("What are your hours?");
  const stats = await ob.stats();
</script>

// Node 18+ / bundlers:
const Onebubbles = require("onebubbles.com/onebubbles.js"); // or a copy
const ob = Onebubbles.createClient(process.env.ONEBUBBLES_KEY);

Endpoints

POST/api/v1/contacts

Create or update a contact

Upsert a CRM contact by email. Returns the contact id and whether it was newly created.

Parameters
email
— required — the contact's email (unique key)
name
— optional — display name
phone
— optional
tags
— optional — array of strings
Request
curl -X POST https://onebubbles.com/api/v1/contacts \
  -H "Authorization: Bearer od_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "email": "jane@acme.com",
    "name": "Jane Doe",
    "tags": ["lead"]
  }'
Response
{
  "ok": true,
  "contactId": "e3a7…",
  "created": true
}
GET/api/v1/contacts

List contacts

List contacts (newest first), or fetch one by email. Filter by tag or lifecycle stage.

Parameters
email
— optional — return the matching contact
tag
— optional — filter by a tag
lifecycle
— optional — lead | active | customer | churned
limit
— optional — 1–200 (default 50)
Request
curl "https://onebubbles.com/api/v1/contacts?lifecycle=customer&limit=50" \
  -H "Authorization: Bearer od_sk_..."
Response
{
  "contacts": [{
    "id": "e3a7…",
    "name": "Jane Doe",
    "email": "jane@acme.com",
    "tags": ["vip"],
    "lifecycleStage": "customer",
    "company": "Acme",
    "blocked": false,
    "lastSeenAt": "2026-07-15T…"
  }]
}
POST/api/v1/messages

Send an inbound message

Inject a message from any custom source into the inbox as the “api” channel. Runs the full pipeline: contact upsert, auto-assignment, AI auto-tagging, agent push, and webhooks.

Parameters
message
— required — the message text
externalId
— required (or email) — a stable per-user id in your system
name
— optional
email
— optional
phone
— optional
Request
curl -X POST https://onebubbles.com/api/v1/messages \
  -H "Authorization: Bearer od_sk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "externalId": "user-123",
    "name": "Jane",
    "email": "jane@acme.com",
    "message": "My order hasn't arrived"
  }'
Response
{
  "ok": true,
  "conversationId": "97…",
  "contactId": "e3…",
  "messageId": "6e…"
}
GET/api/v1/conversations

Read conversations

List conversations (newest first), optionally by contact — or pass conversationId to get a single conversation with its full message transcript.

Parameters
conversationId
— optional — return one conversation + transcript
email
— optional — filter to a contact
contactId
— optional — filter to a contact
status
— optional — open | pending | closed
priority
— optional — high | normal
limit
— optional — 1–100 (default 20)
Request
curl "https://onebubbles.com/api/v1/conversations?email=jane@acme.com" \
  -H "Authorization: Bearer od_sk_..."
Response
{
  "conversations": [{
    "id": "97…",
    "status": "open",
    "channel": "web",
    "tags": ["refund","billing"],
    "priority": "high",
    "language": "en",
    "lastMessagePreview": "Thanks!",
    "rating": null,
    "contact": { "name": "Jane", "email": "jane@acme.com" }
  }]
}
GET/api/v1/stats

Workspace metrics

Summary metrics for building dashboards: conversation counts by status, new conversations in the last 30 days, contact total, and CSAT.

Request
curl https://onebubbles.com/api/v1/stats \
  -H "Authorization: Bearer od_sk_..."
Response
{
  "conversations": {
    "total": 128, "open": 7, "pending": 1,
    "closed": 118, "snoozed": 2, "urgent": 3, "last30d": 40
  },
  "contacts": { "total": 96 },
  "csat": { "average": 4.3, "responseRate": 62, "count": 51 }
}
POST/api/v1/ai/reply

Draft an AI reply

Given a customer message, returns an AI-drafted reply grounded in your knowledge base, plus an escalate flag when a human should step in. Consumes one AI credit.

Parameters
message
— required — the customer's message
Request
curl -X POST https://onebubbles.com/api/v1/ai/reply \
  -H "Authorization: Bearer od_sk_..." \
  -H "Content-Type: application/json" \
  -d '{ "message": "What are your opening hours?" }'
Response
{
  "reply": "We're open Mon–Fri, 9am–6pm…",
  "escalate": false
}

Webhooks

Subscribe to events in Dashboard → Settings → Webhooks. We POST a signed JSON payload to your URL for each event you pick.

conversation.created

A new conversation started

conversation.assigned

A conversation got an owner

conversation.resolved

A conversation was closed

conversation.rated

A visitor submitted a CSAT rating

contact.created

A new contact was added

message.received

An inbound message arrived

Verifying signatures

Each delivery includes an X-Onebubbles-Signature header: sha256=<hex>, an HMAC-SHA256 of the raw request body using your webhook's signing secret. Recompute it and compare to reject spoofed requests.

// Node.js
import crypto from "crypto";

function verify(rawBody, header, secret) {
  const expected =
    "sha256=" + crypto.createHmac("sha256", secret)
      .update(rawBody).digest("hex");
  return header === expected;
}
API Reference — Onebubbles