Skip to content

REST API

Everything the dashboard does is API-first. Interactive OpenAPI reference: /docs on your API host (generated from the same zod schemas that validate requests).

Authentication

Authorization: Bearer wb_...

Keys are org-scoped or app-scoped, with read / write / send / admin scopes. Rate limits are per org, in two lanes: transactional (POST /notifications, batches at one unit per recipient, Live Activity updates — 6,000/min by default) and standard (everything else — 1,200/min). Every authenticated /v1 response carries x-ratelimit-lane, x-ratelimit-limit, x-ratelimit-remaining and x-ratelimit-reset (seconds) for the lane it rode (a refused batch still reports what the lane has left — a refused charge is never counted), a refusal is a 429 with Retry-After, and GET /org/limits shows every allowance — the org-wide daily send cap and today's tally, both lanes' current windows, the per-IP ceiling above them, the batch size, the email allowance and events retention.

Route map (all under /v1)

AreaRoutes
OrgsPOST /orgs (admin bootstrap) · GET/PATCH /org · usage, invoice preview, audit log
Apps & credentialsapps CRUD · POST /apps/:id/credentials/{fcm,apns,twilio,whatsapp,telegram,rcs,line,zalo,viber,kakao} · settings (caps, quiet hours, webhook, email sender, eventsRetentionDays 7–90 or null for the platform's, emailTracking on/off for the open pixel and tracked links)
SuppressionsGET/POST/DELETE /apps/:id/suppressions — record and manage opt-outs (email, SMS, WhatsApp, Telegram, RCS, LINE, Zalo, Viber, KakaoTalk, voice); the worker's send gate honours them on every lane. Phone-number channels (SMS, voice, WhatsApp, RCS, KakaoTalk) share one identity: suppressing a number on any of them silences it on all of them, and DELETE via any of them clears the number
Twilio webhooksPOST /webhooks/twilio/sms-status and /voice-status (the platform-requested outcome callbacks, HMAC-signed under the tenant's auth token: late SMS failures become bounced, dead numbers are pruned, everything keyed on the signed device) · POST /webhooks/twilio/sms-inbound/:appId (point your Twilio number here; X-Twilio-Signature verified; STOP suppresses the phone identity, START lifts it)
WhatsApp webhookGET/POST /webhooks/whatsapp/:appId — Meta Cloud API callbacks, authenticated by X-Hub-Signature-256 with the tenant's Meta app secret (fail-closed without it; GET is the verify-token handshake). read → attributed opened, post-acceptance failedbounced (+device disable on 131026), inbound STOP replies → phone-identity suppression. Redeliveries deduped
Audiencesubscribers (upsert on external id; PATCH /subscribers/:id {preferredChannels} — the channels marketing may use, null = any; honoured by campaigns, fallback and journeys, ignored by the transactional lane; also on /import/subscribers rows and in both exports), devices, tags, bulk import
Message templatesCRUD; templateName on POST /messages and POST /notifications (the latter renders {{ … }} at accept time from variables, the person's tags and language)
Response schemasevery core operation documents its 2xx body and its { error } 4xx bodies in /openapi.json, so generated clients get return types; timestamps are string/date-time, bodies always allow additional properties
Insightsfunnels, cohort retention, RFM, event trends (GET /insights/event-trends?events=&days=&interval=), engagement heatmap (GET /insights/engagement-heatmap?days= — deliveries, opens and clicks by local day of week × hour), subscriber growth (GET /insights/subscriber-growth?days=&interval= — new subscribers per bucket with the running total), channel health (GET /insights/channel-health?days= — delivered / bounced / suppressed / failed and bounce rate per channel), delivery failures (GET /insights/delivery-failures?days=&limit= — sends that failed after every retry, by reason and lane, with whether a redrive has since landed them; the same open failures are failed in every campaign funnel)
SegmentsCRUD + live preview counts
Messagingmessages (incl. localizations; delivery options badgeCount / sound / ttlSeconds / collapseKey / androidChannelId / priority mapped per channel — reserved key names on payload and on transactional data, other-typed values 400; payload.whatsapp = {templateName, languageCode, headerParams?, bodyParams?} references an approved Meta template — required on the base message and every A/B variant of a campaign with channels: ["whatsapp"], and on journey send-step messages targeting whatsapp; params Liquid-rendered per recipient) · campaigns (recurrence, tz, optimal-time, throttle, A/B) · POST /campaigns/:id/send · POST /campaigns/:id/cancel · POST /campaigns/:id/pause / resume (hold a multi-hour send mid-flight or a recurring campaign between occurrences; resume continues where it left off) · GET /campaigns/stats?ids= (live funnels for up to ten, the compare view) · GET /campaigns/export (every campaign with its rollup funnel as text/csv)
TransactionalPOST /apps/:id/notifications — straight to the priority lane; variables render a template's (or inline) {{ … }} at accept time with the person's tags and language, strictly (an unresolved reference is a 400, never an empty message) · GET /apps/:id/notifications/:id — where a send stands (delivered / bounced / failed / suppressed / pending, per-device receipts; send or read scope) · POST /apps/:id/notifications/batch — same lane, up to 1,000 named recipients per call with shared content, per-recipient overrides, per-recipient results and idempotency keys derived from the batch key
JourneysCRUD + PATCH {active} + stats
Live Activitieslist · POST /live-activities/:id/{update,end}
Insightsfunnel, cohorts, RFM
Integrationscatalog GET · per-type PUT/DELETE
BillingGET /org/billing · POST /org/billing/checkout (Stripe-hosted)
White-labelPOST/GET /org/clients · GET/PATCH /org/branding

Public SDK endpoints (appId-scoped, no key)

GET /sdk/app/:appId · POST /sdk/subscriber · POST /sdk/register · POST /sdk/tags · POST /sdk/live-activities · in-app feed — these only let a client create/claim its own records within one app.

Ingest

POST /e on the ingest host: batched events with per-event validation (one malformed event never poisons a batch). Plus POST /i/segment/:appId for Segment inbound.

AI agents

@wingblaze/mcp-server exposes create_campaign, send_campaign, campaign_stats, send_transactional, org_usage, build_segment, create_segment and list_segments as MCP tools — point your agent at it and it can operate WingBlaze directly. Sending is two-phase on purpose: create_campaign returns a draft plus its live audience size, then send_campaign(campaignId) commits, so a retried tool call can never blast an audience twice.

Teknokrat Niaga Sdn Bhd · No. 28-1, Jalan SP 5/2, BSP Business Center, 42610 Bandar Saujana Putra, Selangor, Malaysia · +60 3-5614 3169 · Enquiries: info@teknoniaga.com