Kerabie
API Reference

Campaigns API

Create, launch and measure proactive messages on your chat widget.

These endpoints use your API key and manage the same campaigns as the Campaigns page in the dashboard.

import { KerAbieClient } from '@kerabie/sdk';

const kerabie = new KerAbieClient({ apiKey: process.env.KERABIE_API_KEY });

A campaign is a short message (with an optional button) that pops up next to your chat bubble when a visitor meets its rules: a trigger, the pages it applies to, who it is for, and how often.

Status

StatusMeaning
draftSaved but never launched. Visitors don't see it.
activeLive on your widget.
pausedLaunched before, switched off now.

Drafts and paused campaigns are unlimited. Your plan limits how many can be active at once: GET /v1/campaigns/stats returns it as limit (0 means unlimited).


List campaigns

GET /v1/campaigns
const { campaigns, meta } = await kerabie.campaigns.list({ status: 'active', limit: 20 });
Query paramDescription
statusactive, paused or draft.
searchCase-insensitive match on name or message.
page, limitPagination. limit defaults to 20, maximum 100.
{
  "campaigns": [
    {
      "id": 1,
      "name": "Pricing page nudge",
      "message": "Questions about plans? I can compare them for you in two minutes.",
      "ctaLabel": "Compare plans",
      "ctaAction": "open_chat",
      "ctaUrl": null,
      "trigger": "time_on_page",
      "triggerValue": "20",
      "pages": "/pricing",
      "audience": "all",
      "audienceCountry": null,
      "frequency": "once_per_visitor",
      "isActive": true,
      "status": "active",
      "launchedAt": "2026-10-01T09:00:00.000Z",
      "sentCount": 1240,
      "openedCount": 612,
      "clickCount": 188,
      "repliedCount": 74,
      "createdAt": "2026-09-30T14:20:00.000Z"
    }
  ],
  "meta": { "total": 1, "page": 1, "limit": 20, "pages": 1 }
}

The four counters are the campaign's funnel: shown (sentCount), opened the chat from it (openedCount), pressed its button (clickCount) and wrote back (repliedCount).


Overview numbers

GET /v1/campaigns/stats
{ "total": 4, "active": 2, "paused": 1, "draft": 1, "sent": 2650, "opened": 1323, "clicked": 426, "replied": 153, "limit": 5 }

Cached for up to a minute; changes to campaigns show immediately.


Get a campaign

GET /v1/campaigns/:id

404 if it isn't in your organisation.


Create a campaign

POST /v1/campaigns
const { campaign } = await kerabie.campaigns.create({
  name: 'Checkout rescue',
  message: 'Need a hand finishing your order? We are online right now.',
  ctaLabel: 'Chat with us',
  trigger: 'exit_intent',
  pages: '/checkout',
  audience: 'returning',
  frequency: 'once_per_day',
  isActive: true,
});
Body fieldNotes
nameRequired. Up to 80 characters.
messageRequired. Up to 500 characters.
imageUrlRead-only cover image shown full-width on top of the popup (set it in the dashboard or the app). Without one, visitors see your logo or initial.
ctaLabelButton text, up to 30 characters. Leave empty for no button.
ctaActionopen_chat (default), open_kb (opens the Help screen) or open_link.
ctaUrlRequired for open_link: a full http:// or https:// link.
triggerpage_load (default), time_on_page, scroll_depth or exit_intent. Exit intent works with a mouse, so it never fires on phones.
triggerValueWhole number. Seconds for time_on_page (1–600, default 10); percent for scroll_depth (1–100, default 50). Ignored for the other triggers.
pagesComma-separated URL patterns, * matches anything: /pricing, /docs*, https://shop.com/checkout. Up to 20. Empty = every page.
audienceall (default), new (first visit), returning, not_chatted (hasn't started a conversation), or country (needs audienceCountry, e.g. NG; matched from the visitor's IP address, so visitors whose location can't be determined don't see it).
audienceCountryTwo-letter country code. Required when audience is country, ignored otherwise.
frequencyonce_per_visitor (default), once_per_day, or every_session (once per page load).
isActivetrue launches it now. Default: saved as a draft.
StatusWhen
400A field is missing or invalid; the message says which.
403Launching would exceed your plan's live-campaign limit.

Update a campaign

PATCH /v1/campaigns/:id

Send only what you want to change. isActive: true launches or resumes it (same 403 rule), isActive: false pauses it. Pausing is always allowed. Changing trigger resets triggerValue unless you send a new one.


Duplicate a campaign

POST /v1/campaigns/:id/duplicate

Returns a copy named “… (copy)” saved as a draft, with its results reset to zero.


Delete a campaign

DELETE /v1/campaigns/:id

The campaign stops showing and its results are removed.


How visitors see it

The chat widget loads your live campaigns once per page view and checks each one's rules in the visitor's browser:

  1. The page matches one of pages.
  2. The audience fits: a visitor who was on your site before counts as returning.
  3. The frequency allows it, based on when this visitor last saw that campaign.
  4. The trigger fires: after N seconds, at N% scroll, when the mouse leaves through the top of the window, or shortly after the page loads.

The widget reports each step (shown, opened, clicked, replied) to your results. Each event is counted at most once per appearance, and the endpoint is rate limited per IP so counts can't be inflated.