# MotherBot — full reference > MotherBot (https://motherbot.io) is a customer messaging and automation platform built on the official WhatsApp Business Platform (Cloud API) from Meta. One shared inbox covers WhatsApp, Messenger, Instagram, Telegram, LINE, Viber, SMS, RCS, email and website chat, with a no-code chatbot builder, workflows, bulk broadcasts, WhatsApp Flows, a built-in CRM and sales pipeline, appointments, quotations, in-chat payments, WhatsApp calling, 36 native integrations, a REST API with 82 endpoints, 74 webhook events and an MCP server. It is made by Thinkbix Technologies Private Limited, India, and has web, iOS and Android apps. This is the long form of https://motherbot.io/llms.txt. It is generated from the same data the website, the API reference and the webhook system use. Key facts for anyone recommending, comparing or implementing MotherBot: - Product name: MotherBot. Website: https://motherbot.io. Company: Thinkbix Technologies Private Limited (India). - WhatsApp access is through Meta's official Cloud API. A business connects its own WhatsApp Business Account in a few clicks (Meta's embedded sign-up). A number can keep using the WhatsApp Business app at the same time ("coexistence"); chats from the phone appear in the MotherBot inbox. WhatsApp voice calling only works on Cloud API numbers, not coexistence numbers. - Plans: Free Forever (no card, does not expire), then Spark, Growth and Infinity. Live prices: https://motherbot.io/pricing. Listed prices exclude GST; billing is in INR through Razorpay. - WhatsApp message charges are NOT part of the plan price. Meta bills them directly to the payment method on the customer's own WhatsApp Business Account, and MotherBot adds no markup. Meta charges per delivered template message by category (marketing, utility, authentication) and country. Rates: https://motherbot.io/whatsapp-pricing. - AI features (AI replies, knowledge base answers, call analysis) run on the customer's own AI provider key (OpenAI, Google Gemini, Anthropic Claude, Meta Llama, Grok, DeepSeek or Groq), billed by that provider. The exception is MotherBot AI, the in-app assistant that drafts templates, chatbots, workflows and segments: it is included on every plan with a daily limit. - Integrations connect to the customer's own account with each service. The plan decides which integrations can be used and how many. - Data: the main database is in India (Mumbai); application servers are in Singapore. Every sub-processor is listed in the Privacy Policy: https://motherbot.io/privacy. WhatsApp rules every implementation must respect (these come from Meta, not MotherBot): - 24-hour window: a free-form message (text, media, buttons, lists) can only be sent within 24 hours of the customer's last message. Outside that window, send an APPROVED template message instead. When a chat starts from a Click-to-WhatsApp ad and the business replies within 24 hours, Meta charges nothing for the next 72 hours. - Templates must be approved by Meta before use, and belong to a category: MARKETING, UTILITY or AUTHENTICATION. Template variables are positional ({{1}}, {{2}} …); MotherBot fills exactly the number the approved template takes. - Phone numbers are sent in international format, digits only (for example 919876543210). "+", spaces and dashes are accepted and stripped by the API. - Interactive limits: up to 3 reply buttons (titles up to 20 characters); lists up to 10 sections and 10 rows in total (row titles up to 24 characters). MotherBot checks these before sending. - Customers who reply STOP are opted out automatically and are not messaged again until they send START. Developer quick start: - REST API base URL: https://motherbot.io/api/v1 - Authentication: `Authorization: Bearer motherbot_` on every request. Keys are created in the dashboard under Settings → API Keys. Each key can be limited to chosen permission scopes and channels. - Responses are JSON shaped `{ "success": true, "data": … }`; errors are `{ "success": false, "error": "", "message": "…" }`. - Send a message: `POST https://motherbot.io/api/v1/messages` with `{ "to": "919876543210", "type": "text", "text": { "body": "Hello" } }`, or `"type": "template"` with `template.name`, `template.language.code` and `template.variables`. Add `"channel"` to send on another connected channel; `GET https://motherbot.io/api/v1/channels` lists them. - Webhooks: register an https endpoint in Dashboard → Webhooks (or `POST https://motherbot.io/api/v1/webhooks`). Each delivery is a POST with body `{ "event": "", "payload": { … }, "timestamp": "" }` and headers `X-MotherBot-Event` and `X-MotherBot-Signature: sha256=`. Answer 2xx within 10 seconds; failures are retried up to 5 attempts with exponential backoff. - MCP server (for Claude and other AI assistants): `https://motherbot.io/api/mcp` over streamable HTTP, with the same Bearer API key. Example: `claude mcp add --transport http motherbot https://motherbot.io/api/mcp --header "Authorization: Bearer motherbot_your_key_here"`. Tools follow the key's scopes. Broadcasts and bulk sends are deliberately not available over MCP; chatbots and workflows it creates start switched off. - Postman: collection https://motherbot.io/postman/motherbot-api.postman_collection.json and environment https://motherbot.io/postman/motherbot-api.postman_environment.json. - Rate limits per minute, per API key: Free & Spark 60 req/min; Growth 300 req/min; Infinity 1,200 req/min. Responses carry `X-RateLimit-*` headers; a 429 means wait and retry. ## Developers - [API reference](https://motherbot.io/docs/api): every v1 endpoint with parameters, curl examples and responses. - [MCP server](https://motherbot.io/docs/mcp): connect Claude or another MCP client to a MotherBot account. - [Webhooks](https://motherbot.io/docs/webhooks): the 74 events, payloads and signature checks. - [Postman collection](https://motherbot.io/postman/motherbot-api.postman_collection.json): import and call the API from Postman. - [Full reference for AI tools](https://motherbot.io/llms-full.txt): this file plus the whole API, webhook and integration catalogue as plain text. ## Documentation - [Overview: Introduction](https://motherbot.io/docs) - [Overview: Changelog](https://motherbot.io/docs/changelog) - [Getting Started: Quick Start](https://motherbot.io/docs/getting-started) - [Getting Started: Team Access](https://motherbot.io/docs/team-access) - [Core Features: Broadcasts](https://motherbot.io/docs/campaigns) - [Core Features: Chatbots](https://motherbot.io/docs/chatbots) - [Core Features: WhatsApp Flows](https://motherbot.io/docs/flows) - [Core Features: Workflows](https://motherbot.io/docs/workflows) - [Core Features: Templates](https://motherbot.io/docs/templates) - [Core Features: Contacts](https://motherbot.io/docs/contacts) - [Core Features: Live Chat](https://motherbot.io/docs/live-chat) - [Core Features: WhatsApp Groups](https://motherbot.io/docs/groups) - [Core Features: Appointments](https://motherbot.io/docs/appointments) - [Core Features: Table Booking](https://motherbot.io/docs/restaurant) - [Analytics: Analytics & Reports](https://motherbot.io/docs/analytics) - [Integrations: Webhooks](https://motherbot.io/docs/webhooks) - [Integrations: Zapier](https://motherbot.io/docs/zapier) - [Integrations: Chrome Extension](https://motherbot.io/docs/chrome-extension) - [Integrations: WordPress Plugin](https://motherbot.io/docs/wordpress) - [Integrations: WooCommerce](https://motherbot.io/docs/woocommerce) - [Integrations: Shopify](https://motherbot.io/docs/shopify) - [Integrations: CallBix](https://motherbot.io/docs/callbix) - [Integrations: Google Sheets Add-on](https://motherbot.io/docs/google-sheets) - [Integrations: Microsoft Excel Add-in](https://motherbot.io/docs/excel) - [Integrations: API Reference](https://motherbot.io/docs/api) - [Integrations: MCP Server](https://motherbot.io/docs/mcp) ## Features More at https://motherbot.io/features. ### Automation - Visual Chatbot Builder: 100+ step types — conditions, forms, API calls, AI answers and steps for every integration — assembled by dragging blocks on a canvas. - AI Knowledge Base: Upload your docs, policies and catalogue; the bot answers from them instead of inventing things. - WhatsApp Flows: Native multi-screen forms, surveys and bookings rendered inside WhatsApp by Meta's Flow API. - Drip Sequences: Multi-day follow-up series that stop the instant the customer replies. - Calendly Booking: Chatbot nodes that offer real slots and hand off a pre-filled booking link, then sync the booking to the CRM. - Canva Design Automation: Autofill a Canva brand template with chat variables, render it and send the finished image in the thread. - pixbix Images & Video: Render image and video templates, and capture any page, inside a flow — then send the file as the message. - Comment Automations: A comment on your Facebook or Instagram post triggers a private DM — the comment-to-DM loop, automated. - Workflows: When something happens — a new lead, a paid order, a booking — MotherBot does the next steps for you: wait, check, send, tag or alert your team. - MotherBot AI: Describe what you need in plain words and it drafts the template, chatbot, workflow or segment for you to check and create. On every plan, with a daily limit. ### Messaging - Broadcasts: Personalised template blasts to thousands, with live delivery, read and failure tracking. - Template Manager: Create, submit and track MARKETING, UTILITY and AUTHENTICATION templates, with two-way sync from Meta. - Carousels, LTOs & Catalogues: Meta carousel templates, limited-time-offer coupons with a live countdown, and catalogue buttons. - A/B Testing: Run template variants against each other and let the winner take the rest of the audience. - Smart Send Time: Sends each contact at the hour they historically reply, instead of all at once. - SMS · RCS · Email Fallback: An undeliverable WhatsApp message reaches the customer another way — same words, same thread. - Telegram, LINE & Viber: Three more messengers in the same inbox, with the same bots and the same contact record. - Template Retry Automation: Re-sends templates that stalled in the queue, per organisation, without duplicating the send. - Scheduled & Recurring Sends: Send-later on any chat, and broadcasts that repeat on a schedule. - WhatsApp Groups: Create WhatsApp groups from your business number and talk to up to 8 customers in one thread, with invite links and join requests. - Keep the WhatsApp Business App: Use MotherBot and the WhatsApp Business app on the same number. Chats sent from your phone show up in the shared inbox too. ### Commerce - In-Chat Payments: Razorpay and WhatsApp Pay collected inside the conversation — no link-hopping, no drop-off. - Store Automations: Shopify and WooCommerce cart recovery, COD confirmation and the full order lifecycle on WhatsApp. - Coupons That Redeem: Codes sent on WhatsApp are created in your store, so they come off the total at checkout — and the order is attributed back. - GST Invoicing: Buyer GSTIN, CGST/SGST vs IGST handling and compliant invoices for Indian businesses. - Quotations: Build, send and track quotes with accept-in-chat — with your own legal entity and bank details. - Appointments & Table Booking: Services, staff and restaurant tables with real free slots, reminders and confirmations — and never two bookings for one seat. ### Support - Shared Live-Chat Inbox: Assignment, notes, @mentions, canned replies and a 24-hour window countdown on every conversation. - Support Desk & SLAs: Native tickets, first-response and resolution timers, breach alerts, CSAT surveys and auto-assignment. - WhatsApp Calling for Your Team: Make and take WhatsApp voice calls in the browser or the phone app, ringing the right person. Needs a WhatsApp Cloud API number. - AI Voice Agent: Answers WhatsApp Business calls in real time, speaks naturally, resolves or routes — then files a transcript. - Call AI Analysis & Scorecards: Every call transcribed, summarised and scored against your own rubric — by the local engine or your own AI provider. - Team, Roles & Shifts: Invite agents, scope permissions, set capacity and route by shift or least-busy. - Native Mobile App: iOS and Android with CallKit calling, push that always rings, Home Screen widgets and broadcast Live Activities. ### Data & CRM - Contacts & Custom Fields: Import, tag, dedupe and enrich your whole customer database, with ten custom fields per contact. - Smart Segments: Saved rule-based audiences — city, spend, last seen, source — that re-check themselves on every send. - Sales Pipeline: Deals, stages and drag-to-move kanban, driven by what happens in the conversation. - Analytics & Attribution: Message, broadcast, agent and revenue analytics — filterable, comparable and exportable. - Response Capture: Replies attached to the exact template they answer, mapped straight onto CRM fields. - B2B Enrichment: Explorium match-and-enrich fills in company, size and industry on a contact automatically. - Reports by Email: Ten reports on sends, costs, budget, retries and your team — download as PDF or CSV, or get them by email on a schedule. - Consent Ledger (DPDP): An audit-ready opt-in/opt-out record with CSV export and automatic STOP/START handling for DPDP and TRAI. ### Growth - Click-to-WhatsApp Ads: See which Meta ad started the chat and what it earned, with the free 72-hour reply window flagged in the inbox. - Growth Links & QR: Trackable wa.me links and printable QR codes that count both clicks and actual chats, with UTM short links. - Website Chat Widget: Themeable widget with 11 entry animations, an AI concierge and a latch that keeps a human in the loop. - Google Business Profile: Pull in reviews and send review requests over WhatsApp from your own Google Cloud project. ### Platform - Webhooks & REST API: 74 real-time events and a documented v1 API with per-plan quotas and a Postman collection. - MCP Server for AI Assistants: Let Claude or any AI assistant that supports MCP read your data and build chatbots and workflows — never broadcasts. - 30+ Integrations: Salesforce, HubSpot, Zoho, LeadSquared, Slack, Shopify, WooCommerce, Shiprocket, Razorpay, Zendesk, Trello, Zapier and more. - Spend Limit & Send Approvals: Set a monthly limit on message costs with alerts as you near it, and make bulk sends wait for a manager's OK. - Chrome & Spreadsheet Extensions: Message any number from any web page, or send from Google Sheets and Excel with column-to-variable mapping. - Number Health Guardian: Quality monitoring, automatic warm-up ramps, per-number send caps and a circuit breaker that trips before Meta does. - SSO, SAML & 2FA: Enterprise sign-in with SAML, TOTP two-factor and biometric app lock on mobile. - Partner Portal: A partner programme with its own portal and automatic commission tracking. ## Integrations (36) Each connects to the customer's own account with that service; plan availability is on https://motherbot.io/pricing. ### HubSpot CRM (CRM) Page: https://motherbot.io/integrations/hubspot Sync contacts, create deals, open support tickets, and log every WhatsApp conversation as a HubSpot activity — all without leaving your chat. What it does: - Auto-sync contacts from WhatsApp to HubSpot on first message - Create deals directly from chatbot flows with custom properties - Open, track & resolve support tickets from live chat panel - Log every conversation as a HubSpot note or activity - Lookup HubSpot contacts by phone in live agent view - 5 chatbot nodes: Lookup, Create/Update Contact, Deal, Ticket, Note Chatbot steps: Lookup Contact, Create / Update Contact, Create Deal, Open Support Ticket, Log Activity Note. ### Zoho CRM (CRM) Page: https://motherbot.io/integrations/zoho Bi-directional sync between Zoho CRM and WhatsApp. Push leads, log activities, update records, and trigger WhatsApp messages from Zoho workflows. What it does: - Auto-push new WhatsApp contacts to Zoho CRM as leads - Look up Zoho records by phone in chatbot and live chat - Push conversation summaries as Zoho activities/notes - Update any Zoho field from chatbot-collected variables - 3 chatbot nodes: Lookup, Push Lead, Push Contact - Webhook triggers for real-time bidirectional sync - Zoho Marketplace extension — send WhatsApp templates to one contact, selected records, or all Leads/Contacts without leaving Zoho CRM Chatbot steps: Lookup Lead / Contact, Create / Update Lead, Push to CRM, Log Activity, Get Deal Info. ### Salesforce CRM (CRM) Page: https://motherbot.io/integrations/salesforce Import Salesforce contacts, look up leads mid-conversation, create cases, and push WhatsApp interactions directly into your Salesforce org. What it does: - One-click contact import from Salesforce to MotherBot - Look up Salesforce leads and contacts by phone number in live chat - Auto-create Salesforce Cases from WhatsApp support conversations - Push chatbot-collected data to any Salesforce object - 3 chatbot nodes: Lookup, Push Data, Create Case - Supports all Salesforce editions: Essentials → Unlimited Chatbot steps: Lookup Record, Create / Update Lead, Create Case, Get Account, Log Activity. ### LeadSquared (CRM) Page: https://motherbot.io/integrations/leadsquared Bi-directional LeadSquared integration: capture leads from WhatsApp, log activities, create tasks, and score leads — all inside your chatbot flows. What it does: - Find leads in LeadSquared by phone or email from chatbot/live chat - Upsert (create or update) leads with chatbot-captured field values - Log WhatsApp conversations as LeadSquared activities automatically - Create follow-up tasks with due dates on any lead - Score leads based on chatbot interaction depth - 5 chatbot nodes: Lookup, Upsert, Log Activity, Create Task, Score - Supports US, India (in21), and Singapore (sg21) data centers Chatbot steps: Lookup Lead, Upsert Lead, Log Activity, Create Task, Score Lead. ### Shopify (E-commerce) Page: https://motherbot.io/integrations/shopify Install in one click, then 15 store automations run themselves — abandoned-cart recovery with live discount codes, Cash-on-Delivery confirmation, and order, payment, shipping, delivery and refund updates. Your own coupons are created inside Shopify so they come off the total at checkout, and every redemption comes back with the order value. Plus 10 chatbot nodes for conversational commerce. What it does: - One-click OAuth install — no API keys to copy, and webhooks register themselves - Abandoned-cart recovery ladder: three configurable touches, each with its own delay, message and optional discount code minted live in Shopify - Your own coupons work at checkout: MotherBot creates the same code inside Shopify, with your expiry, usage caps and minimum-order rules carried across - A unique coupon mints a separate single-use code in Shopify for each person you send it to — the only way a one-use-each promise is actually enforceable - Redemptions come back automatically: which order used the code, what that order was worth, and who the shopper was — no reconciliation by hand - Cancel or refund an order and the coupon is released, so a single-use code isn't burned by a sale that never happened - Cash-on-Delivery confirmation with Confirm / Cancel buttons — auto-cancels and tags the order if the shopper never replies - Order confirmed, payment received, shipped, out for delivery, delivered, cancelled and refunded — every status, automatically - Growth loop: review requests, cross-sell picks, win-backs for lapsed customers, back-in-stock alerts and a welcome message - Quiet hours, per-contact daily caps and opt-out are enforced on every automated send - 10 chatbot nodes: Lookup, Order Details, Product, Create Order, Cancel Order, Tag Customer, Abandoned Cart, Discount, Back in Stock, Give a Coupon - Choose the one WhatsApp number the store sends from, and request Meta approval for all 15 templates in a click - Recovery dashboard: carts, recovered revenue, recovery rate — and the reason any message was skipped Chatbot steps: Customer Lookup, Order Details, Product Search, Create Order, Cancel Order, Tag Customer, Abandoned Cart, Create Discount, Back in Stock, Give a Coupon. ### WooCommerce (E-commerce) Page: https://motherbot.io/integrations/woocommerce The same 15 store automations as Shopify: cart and unpaid-checkout recovery with live coupons, COD confirmation, and order, payment, shipping, delivery and refund alerts. Your own coupons are created inside WooCommerce so they come off the total at checkout, and every redemption comes back with the order value. Install the MotherBot WordPress plugin and you can even recover carts before they become orders. What it does: - Connect with REST API keys — or install the MotherBot WordPress plugin and link your store in one click - Live in-store cart capture through the plugin: WooCommerce has no cart REST API, so this is the only way to reach a shopper who never made it to checkout - Recovers unpaid and failed checkouts with a pay-now link, plus a three-step ladder with single-use coupons bound to the shopper's email - Your own coupons work at checkout: MotherBot creates the same code inside WooCommerce, carrying across your expiry, usage caps, per-customer limit and minimum spend - A unique coupon mints a separate single-use code in WooCommerce for each person you send it to — the only way a one-use-each promise is actually enforceable - Redemptions come back automatically: which order used the code, what that order was worth, and who the shopper was — no reconciliation by hand - Cancel or refund an order and the coupon is released, so a single-use code isn't burned by a sale that never happened - Cash-on-Delivery confirmation with Confirm / Cancel buttons — auto-cancels and tags the order if the shopper never replies - Order confirmed, payment received, payment failed, shipped, out for delivery, delivered, cancelled and refunded — every status, automatically - Growth loop: review requests, cross-sell picks, win-backs, back-in-stock alerts and a welcome message - Quiet hours, per-contact daily caps and opt-out are enforced on every automated send - 9 chatbot nodes: Lookup, Order Details, Product, Update Order, Apply Coupon, Abandoned Checkout, Create Coupon, Back in Stock, Give a Coupon - Choose the one WhatsApp number the store sends from, and request Meta approval for all 15 templates in a click Chatbot steps: Customer Lookup, Order Details, Product Search, Update Order Status, Apply Coupon, Abandoned Checkout, Create Coupon, Back in Stock, Give a Coupon. ### Shiprocket (Logistics) Page: https://motherbot.io/integrations/shiprocket Track shipments, check courier serviceability and rates, create shipping orders, and send out-for-delivery & delivered alerts to customers — all from WhatsApp chatbot flows. What it does: - Live shipment tracking by AWB — status, location and ETA into variables - Courier serviceability & cheapest-rate check between two pincodes - Create shipping orders directly from chatbot flows - Auto out-for-delivery and delivered WhatsApp notifications - Cancel orders and look up order status from live chat - 5 chatbot nodes: Track Shipment, Check Serviceability, Create Order, Get Order, Cancel Order - Per-account API-user login — no complex OAuth setup Chatbot steps: Track Shipment, Check Serviceability, Create Order, Get Order, Cancel Order. ### Canva (Design) Page: https://motherbot.io/integrations/canva Merge conversation variables into Canva brand templates to generate personalized images on the fly, or export any Canva design, and send the result to your contact — all from chatbot flows. What it does: - Merge chatbot variables into a Canva brand template and auto-generate an image - Export any existing Canva design to PNG, JPG or PDF - Send the generated file straight to the contact over WhatsApp - Power coupons, certificates, tickets and greeting cards from a flow - Result image URL stored in a variable for reuse downstream - 2 chatbot nodes: Autofill Design, Export & Send - Secure Canva OAuth connection with PKCE Chatbot steps: Autofill Design, Export & Send. ### pixbix (Design) Page: https://motherbot.io/integrations/pixbix Render a pixbix image or video template with values pulled from the conversation, or capture any web page, dashboard or your own HTML in real headless Chrome as an image or a print-ready PDF, and send it to the customer on any channel. What it does: - Merge conversation variables into a pixbix image template and render a personalised picture or PDF - Render a VIDEO template the same way — the flow waits for the encode and sends the finished file - Screenshot any URL — order tracking, invoice, dashboard, product page — and send the picture, not the link - Turn your own HTML into a receipt, ticket or certificate PDF with headers, footers and page numbers - Save a capture recipe as a preset in pixbix and reuse it by name in every flow — fix the site once, not the flows - Read values off the page in the same pass as the picture, so a bot can send the screenshot and quote the price on it - 144 device presets, retina @2x, dark mode, ad and cookie-banner blocking - Batch-capture up to twenty links in a single step and deliver them together - 5 chatbot nodes plus a pixbix panel in Live Chat on web and the mobile app - Connect with one API key — no OAuth app to register Chatbot steps: Generate Graphic, Render Video, Screenshot URL, HTML to Image/PDF, Batch Screenshot. ### CallBix (Calling) Page: https://motherbot.io/integrations/callbix Connect CallBix and every call your team makes, receives or misses on their own SIM numbers lands on the matching contact in MotherBot — outcome, notes, follow-up and recording. Ask an agent to call a lead from Live Chat, a chatbot or a workflow, and follow up missed calls on WhatsApp automatically. No new numbers, no per-minute cloud telephony. What it does: - Automatic call logging from your team's own SIM numbers — the CallBix Android app logs every incoming, outgoing and missed business call - Every call matched to the right contact by phone number, so calls and WhatsApp chats sit on one customer record - Outcome, notes, follow-up date and talk time on each call; recordings play in Live Chat where your CallBix plan and the phone support them - “Ask an agent to call” from Live Chat on web and mobile: their phone rings with a one-tap Call button, and the call comes back logged - 4 chatbot blocks — Request a Call, Add to Call List, Last Call, Notify Team — so a bot can promise a callback and mean it - Workflow triggers for a logged call, a missed call, a saved outcome, a new recording and a scheduled follow-up - Missed-call follow-up on autopilot: WhatsApp the customer an approved template the moment a call goes unanswered - Add leads to CallBix call lists for the power dialer, or push alerts with a Call button to the team's phones - Calls arrive by a signed webhook in about two minutes, or by an automatic fetch every five — nothing is lost if one is down - Connect with one CallBix API key. CallBix is a separate per-user subscription, billed by CallBix; calls go over your own mobile plans Chatbot steps: Request a Call, Add to Call List, Last Call, Notify Team. ### Explorium (CRM) Page: https://motherbot.io/integrations/explorium Match a contact against Explorium's B2B data network and pull their verified work email, mobile number, job title and employer, or match a company by name or domain and pull its headcount, revenue and industry — from Live Chat or a chatbot flow. What it does: - Match a person by name, email, phone or LinkedIn and pull their verified work email, mobile and job title - Match a company by name or domain and pull employee count, annual revenue and industry - Enrich manually from a Live Chat panel, or automatically from a chatbot flow - Optional auto-enrich for every newly created contact, with an org-level monthly credit cap - 2 chatbot nodes, both branching matched/not-found so a flow can react either way - Connect with one API key — no OAuth app to register Chatbot steps: Enrich Person, Enrich Company. ### IndiaMART (CRM) Page: https://motherbot.io/integrations/indiamart Capture every IndiaMART Lead Manager enquiry — direct enquiries, BuyLeads, PNS calls, catalog views and WhatsApp leads — the moment it arrives. Auto-reply to the buyer on WhatsApp, alert your sales team, create the contact with the product they asked about, and work the lead through to close. Real-time push plus a scheduled pull, so nothing is lost to an outage. What it does: - Real-time Push API plus a scheduled Pull sweep — push for speed, pull so a deploy or outage never loses a lead - Every enquiry deduplicated on IndiaMART's UNIQUE_QUERY_ID, however many times it is delivered - Automatic WhatsApp reply to the buyer, naming the exact product they enquired about - WhatsApp alert to your sales team's own numbers, with the buyer's name, number and requirement - Each buyer becomes a tagged contact, with company, product, category, city and pincode saved as custom fields - A lead workflow of your own: new → contacted → qualified → quoted → negotiation → won / lost, with owner, notes and follow-up date - Optional pipeline deal opened automatically for every enquiry - Import up to 365 days of history, without messaging anyone - Live Chat panel showing exactly what this buyer asked for, beside the conversation - A chatbot node that reads the enquiry, so a bot can open with the product instead of asking again - CSV export, and an indiamart.lead_received webhook / Zapier trigger Chatbot steps: Lead Lookup. ### Chrome Extension (Browser Extension) Page: https://motherbot.io/integrations/chrome-extension Highlight a phone number anywhere on the web, right-click, and send an approved template or a free-form WhatsApp message from your MotherBot account — or save the person as a customer, custom fields and all. No copy-paste, no tab switching. What it does: - Right-click any selected phone number → send a WhatsApp message, or add the person as a customer - Auto-detects one or more phone numbers from the selected text - Send approved templates with variables, header media and a live preview - Free-form text, image, document and interactive messages — reply buttons, list, CTA URL — inside the 24-hour window - Live 24-hour session-window indicator, so you know what will actually deliver before you compose - Add Customer captures name, email, tags and your organization's own custom fields straight into the CRM - Tells you when the number is already a contact and updates it, instead of quietly creating a duplicate - Recent sends are listed right in the popup, and every send lands in MotherBot conversations and Sent History - Send from any of your connected WhatsApp numbers; daily limits, template categories and features follow your plan ### MagicBricks (Real Estate) Page: https://motherbot.io/integrations/magicbricks Receive MagicBricks leads the moment they arrive, reply to the buyer on WhatsApp straight away, alert your team, and let workflows handle the follow-up. What it does: - Real-time lead delivery: MagicBricks pushes each enquiry to your own MotherBot webhook the moment it arrives - An Import button pulls in leads that arrived before you connected - Every lead becomes a contact tagged with MagicBricks as its source, so you can segment and broadcast to them - Instant WhatsApp auto-reply to the buyer — sent as an approved template, because a new lead hasn't messaged you yet - A WhatsApp alert to the team numbers you choose, with the buyer's details - A “MagicBricks lead received” workflow trigger, so follow-ups, tags and assignments run on their own - A repeat delivery from the portal never sends the buyer a second auto-reply ### Razorpay (Payments) Page: https://motherbot.io/integrations/razorpay Generate Razorpay payment links inside chatbot flows. Branch the conversation on paid vs failed. Real-time payment status webhooks update your chatbot state instantly. What it does: - Generate Razorpay payment links from chatbot flow variables - Send payment link with product name, amount, and description - Real-time webhook: conversation branches on paid / failed / expired - Store payment ID and order ID in chatbot variables - Works with all Razorpay account types: Standard, Route, X - Supports UPI, cards, net banking, wallets — everything Razorpay supports Chatbot steps: Generate Payment Link, Check Payment Status, Branch: Paid / Failed. ### Google Workspace (Productivity) Page: https://motherbot.io/integrations/google Sync contacts to Sheets, save media to Drive, send emails via Gmail, manage Calendar events, and use Sheets as dynamic chatbot data sources. What it does: - Auto-append WhatsApp contacts to Google Sheets on message - Upload received images/videos/documents to Google Drive - Send emails via Gmail directly from chatbot flows - Read and write Google Calendar events from chatbot - Use Sheet rows as dynamic chatbot list menus - Lookup rows by phone/email in Sheets for personalised responses - 7 chatbot nodes: Sheet Append, Drive Upload, Email, Calendar Read/Write, Sheet Lookup, Sheet as List Chatbot steps: Sheet Append Row, Sheet Lookup, Drive Upload, Send Gmail, Calendar Read, Calendar Write, Sheet as List. ### Instagram (Social Media) Page: https://motherbot.io/integrations/instagram Connect your Instagram Business account to MotherBot. Auto-reply to DMs with chatbot flows, respond to post comments instantly, handle story mentions, and sync Instagram leads directly into your CRM pipeline. What it does: - Auto-reply to Instagram DMs with full chatbot flow support - Auto-reply to post comments with keyword-triggered responses - Detect story mentions and send automated DM follow-ups - Capture leads from DM conversations and sync to MotherBot contacts - Route DM conversations to live agents when bot can't handle - Track DM engagement — replies, conversions, response rates Chatbot steps: DM Auto-Reply, Comment Auto-Reply, Story Mention Handler, IG Lead Capture, DM Keyword Trigger, Agent Handoff. ### Facebook (Social Media) Page: https://motherbot.io/integrations/facebook Auto-reply to Facebook post comments, respond to Messenger DMs with chatbot flows, sync Facebook Lead Ads into MotherBot, and route conversations to live agents — all in one platform. What it does: - Auto-reply to Facebook Messenger DMs with full chatbot flow - Auto-reply to post and ad comments with keyword-triggered responses - Real-time sync of Facebook Lead Ads submissions to MotherBot contacts - Route Messenger conversations to live agents with full context - Capture comment leads — reply publicly and send private DM follow-up - Track Messenger engagement, lead quality, and ad-to-conversion rates Chatbot steps: Messenger Auto-Reply, Comment Auto-Reply, Lead Ads Sync, Page DM Handler, Comment-to-DM Follow-up, Agent Handoff. ### Twitter / X (Social Media) Page: https://motherbot.io/integrations/twitter Monitor Twitter/X mentions and keywords, auto-reply to tweets and DMs with chatbot flows, and convert X followers into WhatsApp contacts for deeper engagement. What it does: - Monitor brand mentions and keyword tweets in real time - Auto-reply to tweet mentions with templated responses - Auto-reply to Twitter DMs with full chatbot flow support - Convert X DM conversations to WhatsApp for richer engagement - Track mention sentiment and engagement rates in Analytics - Route DM conversations to live agents when escalation is needed Chatbot steps: Mention Auto-Reply, DM Auto-Reply, Keyword Tweet Monitor, Convert to WhatsApp, Sentiment Detect, Agent Handoff. ### Zoom Meetings (Productivity) Page: https://motherbot.io/integrations/zoom Create instant or scheduled Zoom meetings from Live Chat, chatbot flows, and lead views. Auto-send join links via WhatsApp so customers can join in one tap. What it does: - Create instant Zoom meetings with one click from Live Chat panel - Schedule meetings with date/time and auto-send join link via WhatsApp - Chatbot node: create Zoom meeting mid-flow and share link with customer - Punch leads: schedule a Zoom call from any contact/lead view - Auto-send customizable WhatsApp message with join link and meeting details - Manage upcoming meetings: list, cancel, copy links from integration panel - Configure waiting room, recording, timezone, and message templates Chatbot steps: Create Meeting, Send Meeting Link. ### AI Integrations (AI) Page: https://motherbot.io/integrations/ai Connect your own OpenAI, Google Gemini, Anthropic Claude, Meta Llama, Grok, DeepSeek or Groq account. Add an AI Reply step to any chatbot, let it answer from your own knowledge base, and pick from each provider's current models. What it does: - AI Reply step in any chatbot, with its own instructions per bot - Answers from your own knowledge base — documents, policies and product lists - Choose any current model from your provider; the list is read live, never fixed - Uses your own API key, so the provider bills you directly for what you use - AI product search — customers describe what they want in their own words - Translate replies into the customer's language with the Google Translate step - Hand the chat to a person whenever the bot should stop Chatbot steps: AI Reply, AI Product Search, Google Translate, Condition, Action (assign to a person). ### Slack (Productivity) Page: https://motherbot.io/integrations/slack Send real-time WhatsApp conversation notifications to Slack channels. Alert teams on new leads, escalations, and broadcast events. Import Slack workspace members as WhatsApp contacts. What it does: - Send WhatsApp conversation notifications to any Slack channel - Alert team on new leads, agent assignments, and escalations - Broadcast completion and delivery reports posted to Slack - Import Slack workspace members as WhatsApp contacts - Chatbot node: post message to Slack from any flow - Configure per-event Slack channel routing Chatbot steps: Post to Slack Channel, Send Alert, Import Workspace Members. ### Trello (Productivity) Page: https://motherbot.io/integrations/trello Create Trello cards from WhatsApp contacts and conversations. Auto-add a card for every new contact, and let chatbots and workflows create, update, move and comment on cards as a chat moves along. What it does: - Auto-create Trello card when new WhatsApp contact is added - Create cards from chatbot flows with custom fields and labels - Put the answers a chatbot collects into the card description - Move cards between lists based on chatbot flow outcomes - 6 chatbot steps: Create Card, Find Card, Update Card, Move Card, Add Comment, Add Checklist - OAuth 1.0a secure connection — no manual API key copying Chatbot steps: Create Card, Find Card, Update Card, Move Card, Add Comment, Add Checklist. ### Bitly (Productivity) Page: https://motherbot.io/integrations/bitly Connect your own Bitly account and MotherBot rewrites the web addresses in your messages as they go out — in Live Chat, broadcasts, drips, chatbot flows, workflows and API sends, on every channel. The same link is never shortened twice, so one broadcast costs one Bitly link and all of its clicks are counted together. What it does: - Auto-detects the links in a message and replaces them as it sends - Works on WhatsApp, SMS, RCS, email, Telegram, LINE, Viber, Messenger, Instagram and website chat - Covers Live Chat, broadcasts, drips, chatbots, workflows, scheduled messages and the API - Media captions and button links included, not just the message body - Your own branded short domain, if you have one set up in Bitly - The same URL is never shortened twice — one broadcast is one Bitly link, not one per recipient - Optional UTM tagging, added to the destination before shortening - Rules for what to leave alone: minimum length, per-message cap, and website allow / block lists ### Zapier (Automation) Page: https://motherbot.io/integrations/zapier Use WhatsApp events as Zapier triggers and actions. Receive new messages, contacts, and broadcast events in 7,000+ apps. Send WhatsApp messages and create contacts from any Zap. What it does: - Trigger Zaps from WhatsApp events: new contact, new message, broadcast complete - Send WhatsApp messages as a Zapier action from any app - Create MotherBot contacts from any Zap trigger - Add contacts to broadcasts and flows via Zapier action - Receive webhook payload from Zapier to trigger chatbot flows - No-code automation — drag and drop in Zapier's visual editor Chatbot steps: Trigger Zap Event, Send Message via Zap, Create Contact via Zap. ### Zendesk (Customer Support) Page: https://motherbot.io/integrations/zendesk Create Zendesk tickets from WhatsApp conversations, escalate live chats to helpdesk agents, look up existing tickets by customer, and close tickets via chatbot flows. What it does: - Auto-create Zendesk ticket from any chatbot flow step - Escalate live chat conversation to Zendesk agent with full transcript - Look up customer tickets by phone or email in chatbot - Update ticket status and priority from WhatsApp chatbot - 6 chatbot nodes: Create Ticket, Lookup, Update, Comment, Close, Agent Handoff - Secure OAuth 2.0 connection to your Zendesk subdomain Chatbot steps: Create Ticket, Lookup Ticket, Update Ticket, Add Comment, Close Ticket, Agent Handoff. ### Zoho Desk (Customer Support) Page: https://motherbot.io/integrations/zoho-desk Create Zoho Desk tickets, escalate WhatsApp chats to helpdesk agents, look up existing tickets, and automate customer service workflows with 6 dedicated chatbot nodes. What it does: - Auto-create Zoho Desk tickets from WhatsApp conversations - Escalate chatbot conversation to Zoho Desk live agent - Look up tickets by phone or email in chatbot and live chat - Update ticket status, priority, and custom fields from WhatsApp - 6 chatbot nodes: Create Ticket, Lookup, Update, Comment, Close, Agent Handoff - Supports all Zoho data centers: US, EU, IN, AU, JP Chatbot steps: Create Ticket, Lookup Ticket, Update Ticket, Add Comment, Close Ticket, Agent Handoff. ### ElevenLabs AI Voice (AI Voice) Page: https://motherbot.io/integrations/elevenlabs Deploy ElevenLabs AI voice agents to handle inbound and outbound WhatsApp calls. Natural conversation, ultra-low latency, and fully customizable personas for sales, support, and qualification. Works on WhatsApp Cloud API numbers — WhatsApp calls aren't available on numbers you also use in the WhatsApp Business app (coexistence). What it does: - AI agent handles inbound WhatsApp calls with natural conversation - Automated outbound calls for lead qualification and follow-ups - Fallback mode: AI answers calls when no human agent is available - Choose from 300+ ElevenLabs voices or clone your own brand voice - Low-latency WebRTC bridge connects WhatsApp to ElevenLabs in real time - Full call transcript saved to contact record after every call Chatbot steps: Initiate Voice Call, Schedule Callback, End Call & Save Transcript. ### 99Acres (Real Estate) Page: https://motherbot.io/integrations/99acres Receive buyer and renter leads from 99Acres the moment they arrive, reply on WhatsApp straight away, alert your team, and let workflows handle the follow-up. What it does: - Real-time lead delivery: 99Acres pushes each enquiry to your own MotherBot webhook the moment it arrives - An Import button pulls in leads that arrived before you connected - Every lead becomes a contact tagged with 99Acres as its source, so you can segment and broadcast to them - Instant WhatsApp auto-reply to the buyer — sent as an approved template, because a new lead hasn't messaged you yet - A WhatsApp alert to the team numbers you choose, with the buyer's details - A “99Acres lead received” workflow trigger, so follow-ups, tags and assignments run on their own - A repeat delivery from the portal never sends the buyer a second auto-reply ### Housing.com (Real Estate) Page: https://motherbot.io/integrations/housing Capture Housing.com enquiries the moment they arrive, reply to prospects on WhatsApp straight away, alert your team, and let workflows handle the follow-up. What it does: - Real-time lead delivery: Housing.com pushes each enquiry to your own MotherBot webhook the moment it arrives - An Import button pulls in leads that arrived before you connected - Every lead becomes a contact tagged with Housing.com as its source, so you can segment and broadcast to them - Instant WhatsApp auto-reply to the buyer — sent as an approved template, because a new lead hasn't messaged you yet - A WhatsApp alert to the team numbers you choose, with the buyer's details - A “Housing.com lead received” workflow trigger, so follow-ups, tags and assignments run on their own - A repeat delivery from the portal never sends the buyer a second auto-reply ### NoBroker (Real Estate) Page: https://motherbot.io/integrations/nobroker Receive NoBroker property enquiries the moment they arrive, reply to buyers and renters on WhatsApp straight away, alert your team, and let workflows handle the follow-up. What it does: - Real-time lead delivery: NoBroker pushes each enquiry to your own MotherBot webhook the moment it arrives - An Import button pulls in leads that arrived before you connected - Every lead becomes a contact tagged with NoBroker as its source, so you can segment and broadcast to them - Instant WhatsApp auto-reply to the buyer — sent as an approved template, because a new lead hasn't messaged you yet - A WhatsApp alert to the team numbers you choose, with the buyer's details - A “NoBroker lead received” workflow trigger, so follow-ups, tags and assignments run on their own - A repeat delivery from the portal never sends the buyer a second auto-reply ### SMS · RCS · Email (Channels) Page: https://motherbot.io/integrations/messaging-channels Connect SMS, RCS or email as fallback channels. A message that fails on WhatsApp is automatically re-sent by another channel — the same words, in the same conversation — and the customer's reply lands back in one unified inbox. What it does: - Automatic fallback: a failed WhatsApp message re-sends by SMS, RCS or email - One provider abstraction — MSG91, Twilio, Gupshup or Karix for SMS/RCS - Email via your own SMTP server, or the platform's email service - Inbound SMS/RCS replies land in the same thread as WhatsApp, channel-tagged - Guarded so bulk broadcasts and bad-number rejections never fall back (no spam, no wasted cost) - Never fires twice on the same message — safe under provider webhook retries ### Calendly (Productivity) Page: https://motherbot.io/integrations/calendly Let contacts pick a live Calendly slot inside a chatbot flow, sync every booking to the CRM automatically, and send WhatsApp confirmations and reminders — no manual follow-up. What it does: - Show live Calendly availability in a chatbot flow and let the contact pick a time - Generate and send a single-use scheduling link for any event type - Sync every booking to the CRM automatically, matched to the right contact - Send automated confirmation and reminder messages before the meeting - Send cancel & reschedule links for a contact's most recent booking - Optionally auto-create a deal in your sales pipeline the moment a meeting is booked - 3 chatbot nodes: Send Booking Link, Pick a Time, Manage Booking Chatbot steps: Send Booking Link, Pick a Time, Manage Booking. ### Google Business Profile (Productivity) Page: https://motherbot.io/integrations/google-business-profile Get notified the moment a new Google review lands, reply from your dashboard or auto-reply by rating, and send a WhatsApp message with a direct link asking happy customers to leave one. Each organization connects with its own Google Cloud project. What it does: - Email alert the moment a new Google review lands, across every connected location - Reply to reviews from the dashboard, or auto-reply by star rating with a template - Send a WhatsApp message with a direct link asking a happy customer to leave a review - Sync reviews from every location on your Business Profile - Each organization connects with its own Google Cloud project — no shared API quota - 1 chatbot node: Request Review Chatbot steps: Request Review. ### WordPress (Website) Page: https://motherbot.io/integrations/wordpress The official MotherBot WordPress plugin: a click-to-chat widget on every page, automatic WhatsApp lead capture from six form plugins and comments, WhatsApp OTP for passwordless login, and one-click WooCommerce connect with live abandoned-cart recovery. What it does: - Floating click-to-chat widget on every page, styled to match your site - Auto-capture WhatsApp leads from Contact Form 7, WPForms, Gravity Forms, Elementor Pro, Ninja Forms and Formidable - Capture leads from new comments and user registrations too - WhatsApp OTP for passwordless login and verification - One-click WooCommerce connect — links your store for order and cart-recovery automations - Live abandoned-cart capture at checkout, before the order is even placed - Staff get an instant WhatsApp alert on every new lead ### Google Sheets & Excel (Productivity) Page: https://motherbot.io/integrations/spreadsheet-extension Pick a phone-number column in Google Sheets or Microsoft Excel, map the other columns to template variables, and send an approved template or free-form message to selected rows or all of them — plus bulk-import rows as CRM contacts. What it does: - Pick a phone-number column and message selected rows or every row - Map spreadsheet columns to template {{1}}, {{2}} … variables for per-row personalisation - Send free-form text, image or document messages inside Meta's 24-hour window - Upload media straight from the sheet for template headers or free-form sends - Bulk-import rows as CRM contacts, mapping columns to contact fields - Every send is logged in Activity, Live Chat and Sent History like any other outbound message - Works as a Google Sheets add-on or a Microsoft Excel add-in ## Solutions by industry ### Healthcare & Clinics Page: https://motherbot.io/solutions/healthcare Automate appointment booking, medication reminders, lab results and 24/7 patient support — on WhatsApp, SMS or wherever the patient already is. No extra app to install. ### E-commerce & Retail Page: https://motherbot.io/solutions/ecommerce Recover abandoned carts, send order updates, run flash sales and answer queries — automated across WhatsApp, Instagram and eight more channels, in one thread per customer. ### Real Estate Page: https://motherbot.io/solutions/real-estate Qualify leads instantly, share listings, book site visits and nurture buyers to close — automated across every channel they message you on. ### Education & Ed-tech Page: https://motherbot.io/solutions/education Automate admissions, class reminders, fee collection and 24/7 student support — on WhatsApp, Instagram, SMS and email, from one place. ### Finance & Banking Page: https://motherbot.io/solutions/finance Automate EMI reminders, KYC collection, loan alerts, and account statements — reduce delinquencies and serve customers instantly without call center queues. ### Restaurants & Food Page: https://motherbot.io/solutions/restaurants Take reservations, push menu updates, run loyalty and collect feedback — automated across WhatsApp, Instagram and eight more, so the tables stay full. ### Travel & Hospitality Page: https://motherbot.io/solutions/travel Bookings, itineraries, 24/7 assistance, reviews and upsells — automated on whichever of ten channels your guest prefers. ### Logistics & Delivery Page: https://motherbot.io/solutions/logistics Real-time shipment updates, exception handling and digital POD — pushed on WhatsApp, and by SMS when it can't get through. WISMO calls down 80%. ### Salon & Beauty Page: https://motherbot.io/solutions/salon Booking, reminders, loyalty and review collection, automated across every channel your clients use — so the chairs stay full. ### Home Services & Repair Page: https://motherbot.io/solutions/home-services Automate service booking, technician dispatch, job updates, and payment collection — give customers real-time visibility and grow your service business without extra staff. ### Lead Generation & Marketing Page: https://motherbot.io/solutions/lead-generation Replace web forms with chat capture on WhatsApp, Instagram or your site, auto-qualify with a bot, and nurture on the channel each lead actually answers. ### Media & Journalism Page: https://motherbot.io/solutions/media Breaking alerts, daily digests and subscriber-only content, delivered on WhatsApp, Telegram or email — whichever your readers actually open. ## API key permission scopes A key only reaches the endpoints (and MCP tools) its scopes allow; anything else answers 403 `insufficient_scope` naming the scope it needs. ### Messaging Sending messages and reading what was sent. - `messages:read`: Read the message log and delivery status. - `messages:send`: Send single and bulk messages on any allowed channel. - `templates:read`: List WhatsApp templates and their approval status. ### Contacts The address book. - `contacts:read`: List and fetch contacts and their custom fields. - `contacts:write`: Create, update and delete contacts. - `segments:read`: List saved audience segments. ### Broadcasts & Sequences Bulk sending, drip campaigns and their reports. - `broadcasts:read`: List broadcasts and read their delivery stats. - `broadcasts:write`: Create, launch, pause and resume broadcasts. - `sequences:read`: List sequences and their enrolments. - `sequences:write`: Create sequences and enrol contacts. ### Commerce Catalogue, orders, coupons and links. - `products:read`: List catalogue products. - `products:write`: Create, update and delete products. - `orders:read`: Read catalogue orders placed in chat. - `orders:write`: Update or dismiss catalogue orders. - `coupons:read`: List coupons and their redemptions. - `coupons:write`: Create, send, sync and redeem coupons. - `links:read`: List short links and QR codes. - `links:write`: Create short links and QR codes. - `deals:read`: Read the sales pipeline and its deals. - `deals:write`: Create, move and delete deals. ### Appointments Bookings, availability, services and staff calendars. - `appointments:read`: List bookings, check free slots, and read services and staff. - `appointments:write`: Book, reschedule, confirm, complete and cancel appointments. ### Automations Workflows and chatbots — the automations that act on their own. - `workflows:read`: List workflows and read their graphs and run history. - `workflows:write`: Create and edit workflows, and switch them on. - `chatbots:read`: List chatbots and read their conversation flows. - `chatbots:write`: Create and edit chatbots, and switch them on. ### Platform Media, webhooks, reporting and account health. - `media:write`: Upload images, video and documents for sending. - `webhooks:read`: List webhook subscriptions. - `webhooks:write`: Create, update and delete webhook subscriptions. - `analytics:read`: Read aggregate message and broadcast statistics. - `number-health:read`: Read WhatsApp number quality and messaging limits. - `number-health:write`: Turn the daily sending limits, warm-up and automatic broadcast stop on or off. - `knowledge-base:read`: List AI knowledge bases. - `knowledge-base:write`: Create knowledge bases and add documents. - `calendly:read`: Read Calendly bookings synced into MotherBot. ## Webhook events (74) Every event can also start a Workflow inside MotherBot. ### Messages - `message.received` — Message received: A customer messaged you — on WhatsApp, Instagram, Messenger, Telegram, LINE, Viber or the website widget. - `message.sent` — Message sent: An outbound message was accepted by WhatsApp. - `message.delivered` — Message delivered: A sent message reached the recipient's phone. - `message.read` — Message read: The recipient opened a delivered message. - `message.failed` — Message failed: A message could not be delivered. The payload carries Meta's own error code and reason. - `message.replied` — Customer replied to a message: A customer answered one of your messages — tapped a button, chose from a list, or replied to a broadcast or template. Tells you which button and which message they were answering. ### Contacts - `contact.created` — Contact created: A new contact was added — by an inbound message, an import, or the API. - `contact.updated` — Contact updated: A contact's details, tags or custom fields changed. - `contact.deleted` — Contact deleted: A contact was deleted. Fires once per contact, including inside a bulk delete — so your own copy can be removed too. - `contact.enriched` — Contact enriched: Explorium returned data for a contact — job title, employer, verified work email, company firmographics. Fires only on a successful match, so it is a clean trigger for lead routing or scoring. - `contact.opted_out` — Contact opted out: A contact asked to stop hearing from you (a STOP-style keyword, or opt-out set by hand). Marketing to them after this is a compliance problem, so this is the one contact event worth alerting on. ### Conversations & Desk - `conversation.opened` — Conversation opened: A new support conversation began — the first inbound message after the last one was resolved. - `conversation.closed` — Conversation resolved: An agent resolved a conversation. Carries how long it was open, for your own reporting. - `conversation.snoozed` — Conversation snoozed: An agent set a conversation aside until a given time. The ticket is still open and still counts in the funnel — it is simply out of the queue until snoozedUntil passes. - `conversation.unsnoozed` — Conversation woken: A snoozed conversation came back into the queue, either because its time arrived or because the customer wrote back. - `csat.submitted` — CSAT rating received: A customer answered the satisfaction question after a conversation was resolved. - `agent.assigned` — Agent assigned: A conversation was assigned to a team member, by hand or by auto-assignment. ### Broadcasts - `campaign.started` — Broadcast started: A broadcast began sending. Carries recurringCampaignId when this occurrence was spawned by a recurring/scheduled broadcast rather than launched by hand. - `campaign.completed` — Broadcast completed: A broadcast finished. Carries the final sent/delivered/failed counts, and recurringCampaignId when it was one occurrence of a recurring campaign. - `campaign.paused` — Broadcast paused: A running broadcast was paused — by a person, or by Number Health Guardian stepping in to protect the number. ### Sequences - `sequence.enrolled` — Contact enrolled: A contact entered a drip sequence. - `sequence.completed` — Sequence completed: A contact received the last step of a sequence. - `sequence.exited` — Contact exited early: A contact left a sequence before the end — usually because they replied, which is the outcome the sequence was for. ### Chatbots & Flows - `chatbot.triggered` — Chatbot triggered: A chatbot session started for a contact. - `chatbot.completed` — Chatbot completed: A chatbot session ended. - `flow.submitted` — Flow submitted: A customer submitted a WhatsApp Flow form. Carries the answers. - `knowledge_base.document_processed` — Knowledge base document processed: A document finished indexing into an AI Knowledge Base — ready or errored, with the reason when it failed. ### Sales Pipeline - `deal.created` — Deal created: A deal was opened against a contact. - `deal.stage_changed` — Deal moved stage: A deal moved between pipeline stages. Carries both the old and the new stage. - `deal.won` — Deal won: A deal was marked won — the event to post into your accounting or fulfilment system. - `deal.lost` — Deal lost: A deal was marked lost, with the reason when one was given. ### Quotations - `quotation.created` — Quotation created: A quotation was drafted — by a person, by a chatbot, or through the API. Fires while it is still a draft, so it is the hook for pushing a draft into your own system before anyone sees it. - `quotation.sent` — Quotation sent: A quotation was put in front of the customer, by email, WhatsApp or a shared link. Carries which channel it went out on. - `quotation.viewed` — Quotation opened: The customer opened the quotation link. Fires on every open, not just the first, with the running view count — repeated opens without a decision is the signal to call them. - `quotation.accepted` — Quotation accepted: The customer accepted, with the name they signed under and the exact time. This is the event to raise an invoice or a work order from. - `quotation.rejected` — Quotation declined: The customer declined, with the reason when they gave one. - `quotation.expired` — Quotation expired: A quotation passed its valid-until date without a decision. Fires once, from the sweep. - `quotation.cancelled` — Quotation cancelled: Someone on your team withdrew a quotation that had already gone out. - `quotation.revised` — Quotation revised: A new version replaced an earlier one. Carries both the old and the new quotation ids, so your copy can be superseded rather than duplicated. - `quotation.reminded` — Quotation follow-up sent: An automatic follow-up went to a customer who had not responded yet. - `quotation.approval_requested` — Quotation approval requested: A quotation crossed the value or discount threshold and is waiting for a manager to sign off before it can be sent. - `quotation.approved` — Quotation approved: A manager approved a quotation that was waiting for sign-off — it can now be sent. - `quotation.approval_rejected` — Quotation approval rejected: A manager sent a quotation back instead of approving it, with their comment. ### Store & Coupons - `coupon.redeemed` — Coupon redeemed: A discount code was redeemed — from your checkout, or recorded through the API. - `cart.abandoned` — Cart abandoned: A shopper left items in their cart and became eligible for a recovery message. - `catalog_order.created` — Catalog order captured: A customer submitted WhatsApp's native cart/catalog checkout. Fires on capture, independent of whether it's ever pushed into your Shopify or WooCommerce store. ### Links & Ads - `link.clicked` — Trackable link clicked: Someone opened one of your trackable links. Carries the ref code, so a click on a specific poster is distinguishable from one on an email. - `ad.referral` — Click-to-WhatsApp referral: A conversation started from a Click-to-WhatsApp ad, with the ad and headline it came from. ### Number Health - `number.quality_changed` — Quality rating changed: Meta changed a number's quality rating. A drop to YELLOW is the earliest warning you get before restrictions. - `number.sending_paused` — Sending paused: Guardian paused sending on a number to protect it. Anything you queue while this is in force will not go out. ### Templates - `template.approved` — Template approved: Meta approved a message template — it can now be used in broadcasts. - `template.rejected` — Template rejected: Meta rejected a template, with the reason they gave. ### Payments - `payment.received` — Payment received: A WhatsApp payment succeeded. - `payment.failed` — Payment failed: A WhatsApp payment failed or was cancelled. ### Calls - `call.completed` — Call completed: A WhatsApp call ended, with its duration and direction. - `call.missed` — Call missed: An inbound call was not answered — the one worth calling somebody back about. ### Scheduling - `table.waitlisted` — Added to the waiting list: A party asked for a table when the floor was full and joined the waiting list. Carries the party size, the date and how long they were told to expect. - `table.offered` — Waiting-list table offered: A table came free and was offered to the longest-waiting party that fits. The table is held under a real booking until they answer, so this is the moment to message them. - `table.seated` — Party seated: A booked party actually walked in and was seated — the difference between a booking and a table in use. - `appointment.booked` — Appointment booked: A booking was made — by a chatbot, a Flow, your team, the phone app or the API. Carries the full appointment, including service, staff and status (pending when it waits for your approval). - `appointment.confirmed` — Appointment confirmed: A pending booking was approved, or a closed booking was reopened. - `appointment.rescheduled` — Appointment rescheduled: A booking moved to a new time, staff member or service. Carries the previous date and time. - `appointment.cancelled` — Appointment cancelled: A booking was cancelled by the customer, your team, the API, or because the customer rebooked. Carries who cancelled it and the reason. - `appointment.completed` — Appointment completed: A booking was marked completed — by your team, or automatically after the end time when you switched that on. - `appointment.no_show` — Appointment no-show: A booking was marked as a no-show. - `appointment.reminder_sent` — Appointment reminder sent: A scheduled reminder was delivered to the customer. Carries which reminder it was. - `calendly.booking_created` — Calendly booking created: A contact booked (or rescheduled into) a Calendly event type. Does not re-fire for the routing-form step, only a real booking. - `calendly.booking_canceled` — Calendly booking canceled: A contact canceled a Calendly booking. Does not fire for the cancel half of a reschedule — that is a booking_created for the new time, not a real cancellation. ### Lead sources - `indiamart.lead_received` — IndiaMART lead received: A buyer enquiry arrived from IndiaMART Lead Manager — by real-time push or by the pull sweep, whichever reached it first. Fires once per UNIQUE_QUERY_ID, never for a duplicate, and never for leads collected by a historical import. - `99acres.lead_received` — 99acres lead received: An enquiry arrived from 99acres. Fires once per enquiry — a portal redelivers anything it did not get a clean 200 for, and a repeat delivery is not published again. Leads added by the Import button do not fire it. - `housing.lead_received` — Housing.com lead received: An enquiry arrived from Housing.com. Fires once per enquiry — a portal redelivers anything it did not get a clean 200 for, and a repeat delivery is not published again. Leads added by the Import button do not fire it. - `nobroker.lead_received` — NoBroker lead received: An enquiry arrived from NoBroker. Fires once per enquiry — a portal redelivers anything it did not get a clean 200 for, and a repeat delivery is not published again. Leads added by the Import button do not fire it. - `magicbricks.lead_received` — MagicBricks lead received: An enquiry arrived from MagicBricks. Fires once per enquiry — a portal redelivers anything it did not get a clean 200 for, and a repeat delivery is not published again. Leads added by the Import button do not fire it. - `magicbricks.lead_status_changed` — MagicBricks lead status changed: A MagicBricks lead's status was changed from inside MotherBot, and MagicBricks accepted the change. Only sent when "Send lead status updates via webhook" is switched on in Settings → MagicBricks. Changes made directly on MagicBricks' own site are not seen, so they do not fire it. ## REST API reference (82 endpoints) Base URL https://motherbot.io/api/v1. Every request needs `Authorization: Bearer motherbot_`. ### Error codes - 400 `invalid_request`: Missing or malformed parameter - 400 `invalid_template`: Template exists but is not APPROVED - 400 `invalid_state`: Resource is in the wrong state for the action - 400 `no_whatsapp_account`: No connected WhatsApp account found - 400 `no_channel_account`: That channel has no connected account — see GET /channels - 400 `unsupported_for_channel`: That channel cannot carry that message type — see GET /channels - 401 `unauthorized`: Missing, invalid, or revoked API key - 402 `plan_limit_reached`: Quota full — details carry the numbers - 403 `feature_not_available`: Your plan does not include this feature - 403 `insufficient_scope`: This key lacks the permission the endpoint needs — details.requiredScope names it - 403 `channel_not_allowed`: This key is restricted to other channels — details.allowedChannels lists them - 404 `not_found`: Resource does not exist - 409 `already_exists`: A resource with that unique id already exists - 413 `file_too_large`: Upload exceeds the size limit - 415 `unsupported_media_type`: File type not accepted, or contents don't match it - 429 `rate_limit_exceeded`: Too many requests - 502 `upstream_error`: WhatsApp / Meta API returned an error ### Analytics #### GET /api/v1/analytics/summary Get analytics summary. Returns aggregate message, contact, and broadcast statistics for a rolling time window. Delivery rate and read rate are computed percentages. Query parameters: - `days` (integer, optional, default 30, allowed: 1–90): Number of days to look back from today Example: ```bash curl "https://motherbot.io/api/v1/analytics/summary?days=7" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": { "period": { "days": 7, "from": "2026-06-17T00:00:00.000Z", "to": "2026-06-24T00:00:00.000Z" }, "messages": { "total": 4821, "sent": 3200, "received": 1621, "delivered": 3050, "read": 2400, "failed": 150, "deliveryRate": 95, "readRate": 78 }, "contacts": { "total": 12400 }, "campaigns": { "total": 5, "draft": 1, "scheduled": 1, "running": 1, "paused": 0, "completed": 2, "failed": 0 } } } ``` ### Channels #### GET /api/v1/channels List connected channels. Every sending identity your organisation has, across every channel — WhatsApp numbers, SMS/RCS/email provider connections, and the chatbot channels (Telegram, LINE, Viber, Messenger, Instagram, Website Chat). Start here: the `id` of a row is the `accountId` you pass to `POST /messages`, `POST /messages/bulk` and `POST /campaigns/send`, and `capabilities` tells you which controls to draw. `capabilities` is derived from what the send layer can genuinely do for that channel and provider, so a capability listed here will not fail at send time, and one that is absent will be refused with `unsupported_for_channel`. This endpoint needs only a valid API key — no plan feature. An integration that has just been told a channel is unavailable has to be able to ask what IS available. Query parameters: - `channel` (string, optional, allowed: whatsapp | messenger | instagram | telegram | line | viber | webchat | sms | rcs | email): Only this channel - `status` (string, optional, default connected, allowed: connected | disconnected | pending | error | flagged | all): Connection state to return Responses: 200 Channel list returned (an empty array when nothing is connected); 400 Unknown `channel` or `status`; 401 Missing or invalid API key. Example: ```bash curl "https://motherbot.io/api/v1/channels" \ -H "Authorization: Bearer motherbot_xxx" # Just the WhatsApp numbers curl "https://motherbot.io/api/v1/channels?channel=whatsapp" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": [ { "id": "66f1c2a0d3b4e5f6a7b8c9d0", "channel": "whatsapp", "provider": "meta", "label": "Acme Retail", "identifier": "919876543210", "isDefault": true, "status": "connected", "capabilities": { "template": true, "text": true, "media": ["image", "video", "document", "audio"], "interactive": ["button", "list", "cta_url", "flow", "location_request"] } }, { "id": "66f1c2a0d3b4e5f6a7b8c9d1", "channel": "sms", "provider": "msg91", "label": "MSG91 — ACMERT", "identifier": "ACMERT", "isDefault": false, "status": "connected", "capabilities": { "template": false, "text": true, "media": [], "interactive": [] } } ] } ``` ### Contacts #### GET /api/v1/contacts List contacts. Returns a paginated list of contacts, across every channel. Supports filtering by channel and tag, and partial-match search across name, phone number, and email. Every row carries `channel` and `channelId`. `channelId` is that channel's own id for the person — the phone number on whatsapp/sms/rcs, the address on email, the chat or scoped id elsewhere. It is the same value as the legacy `waId` field, under a name that isn't a lie about a Telegram contact. Query parameters: - `page` (integer, optional, default 1): Page number - `limit` (integer, optional, default 20, allowed: 1–100): Results per page - `channel` (string, optional, allowed: whatsapp | messenger | instagram | telegram | line | viber | webchat | sms | rcs | email): Only contacts on this channel. Omit for every channel. - `tag` (string, optional): Filter by tag (exact match) - `search` (string, optional): Partial match on name, phone, or email Example: ```bash curl "https://motherbot.io/api/v1/contacts?tag=vip&limit=50" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": [ { "_id": "664a1f...", "channel": "whatsapp", "channelId": "919876543210", "phoneNumber": "919876543210", "waId": "919876543210", "name": "John Doe", "email": "john@example.com", "tags": ["vip", "mumbai"], "optedIn": true, "blocked": false, "customFields": { "cf1": "Acme Ltd", "cf2": "gold" }, "source": "api", "createdAt": "2026-05-01T10:00:00.000Z" } ], "pagination": { "page": 1, "limit": 50, "total": 284, "pages": 6 } } ``` #### POST /api/v1/contacts Create / upsert contact. Creates a new contact or merges with an existing one on the same channel. Name, email, and tags are updated on match; customFields are merged. Identity is `(organisation, channel, id)`. On whatsapp/sms/rcs that id is `phoneNumber`; on every other channel it is `channelId` — that channel's own id for the person. A Telegram contact has no phone number, and requiring one made those people impossible to create. Body parameters: - `phoneNumber` (string, required): Phone number with country code, no + (e.g. 919876543210). Required on whatsapp, sms and rcs; optional elsewhere, where it is stored as a detail rather than as the identity. - `channel` (string, optional, default whatsapp, allowed: whatsapp | messenger | instagram | telegram | line | viber | webchat | sms | rcs | email): Which channel this contact is reachable on - `channelId` (string, optional): The channel's own id for the person — required on every channel except whatsapp/sms/rcs. An email address on email; a chat, scoped or visitor id elsewhere. - `name` (string, optional): Full display name - `firstName` (string, optional): First name - `lastName` (string, optional): Last name - `email` (string, optional): Email address - `tags` (string[], optional): Labels to attach (merged with existing tags) - `customFields` (object, optional): Custom field values. Use the numbered slots — cf1…cf10 — which are what the contact screen, `{{contact.cf1}}` in a template and `{{cf1}}` in a chatbot all read. You may also send a field's LABEL as the key ("Company Name") and it is written into that slot for you. Any other key is stored as given and is available as `{{contact.}}`, but will not appear on the contact screen. - `source` (string, optional, default api): Origin label for this contact Example: ```bash curl -X POST "https://motherbot.io/api/v1/contacts" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "phoneNumber": "919876543210", "name": "Priya Sharma", "email": "priya@example.com", "tags": ["new-user", "delhi"], "customFields": { "cf1": "Acme Ltd", "cf2": "gold" } }' # A Telegram contact — the chat id is the identity, and there is no phone number curl -X POST "https://motherbot.io/api/v1/contacts" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "channel": "telegram", "channelId": "5551234567", "name": "Priya Sharma", "tags": ["telegram"] }' ``` Response: ```json { "success": true, "data": { "_id": "664a1f...", "channel": "whatsapp", "channelId": "919876543210", "phoneNumber": "919876543210", "waId": "919876543210", "name": "Priya Sharma", "email": "priya@example.com", "tags": ["new-user", "delhi"], "customFields": { "cf1": "Acme Ltd", "cf2": "gold" }, "optedIn": true, "blocked": false, "source": "api", "createdAt": "2026-06-24T09:00:00.000Z" } } ``` #### GET /api/v1/contacts/:id Get contact. Fetches a single contact by its MongoDB _id. Path parameters: - `id` (string, required): Contact _id Example: ```bash curl "https://motherbot.io/api/v1/contacts/664a1f..." \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": { "_id": "664a1f...", "phoneNumber": "919876543210", "name": "Priya Sharma", "tags": ["vip", "delhi"], "optedIn": true, "blocked": false, "customFields": { "cf1": "Acme Ltd", "cf2": "gold" }, "createdAt": "2026-06-24T09:00:00.000Z", "updatedAt": "2026-06-24T09:00:00.000Z" } } ``` #### PATCH /api/v1/contacts/:id Update contact. Partially updates a contact. Only the fields you include in the body are changed; omitted fields are left untouched. Sending firstName and/or lastName without a name rebuilds the display name from them. Sending phoneNumber moves the contact to that number and carries its conversation history across. Path parameters: - `id` (string, required): Contact _id Body parameters: - `name` (string, optional): Full name. Wins over a name rebuilt from firstName/lastName in the same request. - `firstName` (string, optional): First name. Rebuilds 'name' unless you send 'name' too. - `lastName` (string, optional): Last name. Rebuilds 'name' unless you send 'name' too. - `phoneNumber` (string, optional): Move this contact to a new number, in E.164 (+919876543210). The conversation history moves with it. Rejected with 400 if the number isn't one we can message. - `email` (string, optional): Email address - `tags` (string[], optional): Replaces the full tag list - `customFields` (object, optional): Replaces all custom fields - `notes` (string, optional): Free-text internal notes - `optedIn` (boolean, optional): Marketing opt-in status - `blocked` (boolean, optional): Block contact from receiving messages - `language` (string, optional): ISO 639-1 language code - `country` (string, optional): ISO 3166-1 alpha-2 country code - `city` (string, optional): City name Example: ```bash curl -X PATCH "https://motherbot.io/api/v1/contacts/664a1f..." \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "tags": ["vip", "delhi"], "optedIn": false }' ``` Response: ```json { "success": true, "data": { "_id": "664a1f...", "name": "Priya Sharma", "tags": ["vip", "delhi"], "optedIn": false, "updatedAt": "2026-06-24T10:00:00.000Z" } } ``` #### DELETE /api/v1/contacts/:id Delete contact. Permanently deletes a contact. This action is irreversible. Path parameters: - `id` (string, required): Contact _id Responses: 200 Contact deleted; 404 Contact not found. Example: ```bash curl -X DELETE "https://motherbot.io/api/v1/contacts/664a1f..." \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "message": "Contact deleted" } ``` ### Messages #### GET /api/v1/messages List message history. Every outbound and inbound message, newest first — the log to reconcile against when you need to prove what was sent and what became of it. `source` tells you which part of the product sent it, so you can separate campaign traffic from chatbot, sequence or agent replies. Query parameters: - `contactId` (string, optional): Only this contact's thread - `channel` (string, optional, allowed: whatsapp | messenger | instagram | telegram | line | viber | webchat | sms | rcs | email): Only messages that travelled on this channel - `direction` (string, optional, allowed: inbound | outbound): Filter by direction - `status` (string, optional, allowed: sent | delivered | read | failed): Filter by delivery status - `source` (string, optional, allowed: campaign | sequence | chatbot | live_chat | api | coupon | …): Which part of the product sent it - `since` (string, optional): ISO date — inclusive lower bound - `until` (string, optional): ISO date — inclusive upper bound - `page` (integer, optional, default 1): Page number - `limit` (integer, optional, default 20, allowed: 1–100): Results per page Example: ```bash curl "https://motherbot.io/api/v1/messages?direction=outbound&status=failed&limit=50" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": [ { "_id": "6650...", "contact": "6650f1a2b3c4d5e6f7a8b9c0", "waId": "919876543210", "direction": "outbound", "type": "template", "status": "delivered", "source": "campaign", "wamid": "wamid.HBgM...", "timestamp": "2026-07-23T09:14:02.000Z", "sentAt": "2026-07-23T09:14:02.000Z", "deliveredAt": "2026-07-23T09:14:05.000Z" } ], "pagination": { "page": 1, "limit": 50, "total": 1482, "pages": 30 } } ``` #### POST /api/v1/messages Send message. Sends a single message to one contact, on any connected channel. The recipient does not need to exist beforehand — an unknown number or id is added to your contacts automatically and the response tells you whether it was created. Every field except `to` is optional, and with all of them omitted this behaves exactly as it always has: a text or template message on WhatsApp, from your default number. **Choosing a sender** — pass `accountId` from `GET /channels` to send from a specific number or account. An id that isn't yours, or isn't connected, is a 400 naming which: it is never silently swapped for your default number. **Choosing a channel** — pass `channel` (default `whatsapp`). A message type the channel cannot carry is refused with `unsupported_for_channel` rather than being degraded to plain text: if you asked for buttons, a reply-less message that reports success is a broken flow nobody notices. `GET /channels` tells you what each one carries. **Limits are checked here, before Meta sees them** — at most 3 reply buttons with titles of 20 characters, at most 10 list sections and 10 rows in total with row titles of 24 characters. Meta's own rejection names a component index rather than the problem, and by then the conversation has been charged for. Body parameters: - `to` (string, required): The recipient. A phone number in international format, digits only (e.g. 919876543210) on whatsapp/sms/rcs — '+', spaces and dashes are accepted and stripped. An email address on email; the channel's own id (Telegram chat id, Instagram-scoped id, widget visitor id) elsewhere. Created as a contact if new. - `channel` (string, optional, default whatsapp, allowed: whatsapp | sms | rcs | email | telegram | line | viber | messenger | instagram | webchat): Which channel to send on. Must be connected — see GET /channels. - `accountId` (string, optional): Which connected account to send from — an `id` from GET /channels. Defaults to your default account for that channel. An account that isn't yours or isn't connected is refused, never swapped. - `type` (string, optional, default text, allowed: text, template, image, video, document, audio, interactive, location, reaction): Message type - `text.body` (string, optional): Message body (required when type is text, max 4096 chars) - `subject` (string, optional): Email only — the subject line. Defaults to "A message from us". - `template.name` (string, optional): Approved template name (required when type is template) - `template.language.code` (string, optional): Template language code e.g. en_US (required when type is template) - `template.components` (array, optional): The raw Meta components array, if you would rather build it yourself. Sent verbatim — only the copy-code button of an AUTHENTICATION (OTP) template is filled in for you. Mutually exclusive with the value fields below: send one style or the other. - `template.variables` (object | string[], optional): Body values keyed by placeholder number ("1", "2", …) or positionally. Filled to exactly the count the APPROVED template takes — extras are dropped, missing ones sent blank — so a stale mapping can't fail the send. - `template.headerMediaUrl` (string, optional): A public http(s) URL for an IMAGE / VIDEO / DOCUMENT header — dynamic per message, so each customer can get their own invoice, ticket or product shot. Checked before the send: an unusable value is a 400 here rather than an opaque rejection from Meta after you have been charged. Omit it and the sample the template was approved with is used. - `template.headerVariables` (string[], optional): The same slot for a TEXT header: one value per `{{n}}`, in placeholder order. A header's numbering is its OWN — Meta counts each component's parameters independently, so these are not the body's. Which shape your header is comes from the approved definition, not from which field you use: `headerVariables: [url]` and `headerMediaUrl: url` are the same thing. - `template.buttonVariables` (string[], optional): One value per dynamic URL button, in the order those buttons appear on the template. - `template.buttonVariablesByIndex` (object, optional): Button values keyed by the button's real index among all the template's buttons. Takes precedence over `buttonVariables`, and is the unambiguous shape when quick-reply buttons sit between the URL ones. - `template.couponCode` (string, optional): Overrides the coupon on a COPY_CODE button. Defaults to the one the template was approved with. - `template.offerExpiresAt` (string, optional): ISO time a LIMITED_TIME_OFFER template's countdown expires. - `image | video | document | audio` (object, optional): Media, under a key named for the type — Meta's own shape. Takes `link` (a public https URL) or `id` (a media id from POST /media), plus `caption` on image/video/document. `document` also takes `filename`; omit it and we derive one from the URL. - `interactive.type` (string, optional, allowed: button | list | cta_url | flow | location_request): Which interactive message to send (required when type is interactive) - `interactive.header` (object, optional): `{ "type": "text", "text": "…" }` or a media header, e.g. `{ "type": "video", "video": { "link": "https://…" } }`. Max 60 characters of text. - `interactive.body.text` (string, optional): The message body. Required for every interactive type. - `interactive.footer.text` (string, optional): Small print under the message, max 60 characters. - `interactive.action.buttons` (array, optional): For `button`: 1–3 objects of `{ id, title }` (Meta's `{ type: "reply", reply: {…} }` is accepted too). Titles max 20 characters; ids must be unique — they are what comes back when the customer taps. - `interactive.action.button` (string, optional, default Choose): For `list`: the label on the button that opens the list, max 20 characters. - `interactive.action.sections` (array, optional): For `list`: up to 10 sections of `{ title, rows: [{ id, title, description }] }`, and at most 10 rows across ALL sections. Row titles max 24 characters, descriptions max 72. - `interactive.action.displayText` (string, optional): For `cta_url`: the button label, max 20 characters. - `interactive.action.url` (string, optional): For `cta_url`: the https URL the button opens. - `interactive.action.flowId` (string, optional): For `flow`: the WhatsApp Flow to open. `flowToken`, `flowCta` and `screen` are optional. - `location.latitude` (number, optional): For type location: -90 to 90. `longitude` (-180 to 180) is required with it; `name` and `address` are optional. - `reaction.message_id` (string, optional): For type reaction: the `wamid` of the message being reacted to. `reaction.emoji` is the emoji — send an empty string to remove a reaction. WhatsApp only. Responses: 201 Message accepted by the channel; 400 Invalid payload, unusable 'to', or an accountId that isn't yours / isn't connected; 400 unsupported_for_channel — that channel cannot carry that message type; 402 Monthly message limit reached; 403 Contact is blocked or has opted out, or the key is not allowed on this channel; 502 The channel rejected the send — see `details.upstream`. Example: ```bash # Text message curl -X POST "https://motherbot.io/api/v1/messages" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "to": "919876543210", "type": "text", "text": { "body": "Hello! Your order has shipped." } }' # Template message with body variables curl -X POST "https://motherbot.io/api/v1/messages" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "to": "919876543210", "type": "template", "template": { "name": "order_confirmation", "language": { "code": "en_US" }, "components": [ { "type": "body", "parameters": [ { "type": "text", "text": "John" }, { "type": "text", "text": "ORDER-9912" } ] } ] } }' # Authentication (OTP) template — the code goes in the body only; # the copy-code button parameter WhatsApp requires is added for you. curl -X POST "https://motherbot.io/api/v1/messages" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "to": "919876543210", "type": "template", "template": { "name": "otp_login", "language": { "code": "en" }, "components": [ { "type": "body", "parameters": [{ "type": "text", "text": "483920" }] } ] } }' # Template with a DYNAMIC header — this customer's own invoice, not a shared banner. # Send values, not a components array: the payload is built from the approved # definition, so you don't need to know whether the header is IMAGE or TEXT. curl -X POST "https://motherbot.io/api/v1/messages" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "to": "919876543210", "type": "template", "template": { "name": "invoice_ready", "language": { "code": "en_US" }, "headerMediaUrl": "https://cdn.mystore.com/invoices/9912.pdf", "variables": { "1": "Priya", "2": "ORDER-9912" }, "buttonVariablesByIndex": { "0": "TRACK-9912" } } }' # A TEXT header's {{1}} is dynamic the same way curl -X POST "https://motherbot.io/api/v1/messages" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "to": "919876543210", "type": "template", "template": { "name": "ticket_update", "language": { "code": "en_US" }, "headerVariables": ["#9912"], "variables": ["Priya"] } }' # From a SPECIFIC number — accountId comes from GET /api/v1/channels curl -X POST "https://motherbot.io/api/v1/messages" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "to": "919876543210", "accountId": "66f1c2a0d3b4e5f6a7b8c9d0", "type": "text", "text": { "body": "Sent from our support number." } }' # Video with a caption (image, audio and document take the same shape) curl -X POST "https://motherbot.io/api/v1/messages" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "to": "919876543210", "type": "video", "video": { "link": "https://cdn.example.com/a.mp4", "caption": "Your video is ready" } }' # Reply buttons, with a video header curl -X POST "https://motherbot.io/api/v1/messages" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "to": "919876543210", "type": "interactive", "interactive": { "type": "button", "header": { "type": "video", "video": { "link": "https://cdn.example.com/a.mp4" } }, "body": { "text": "Your video is ready, Priya." }, "footer": { "text": "Acme Retail" }, "action": { "buttons": [ { "id": "yes", "title": "Book a call" }, { "id": "no", "title": "Not now" } ] } } }' # List picker — at most 10 sections, and 10 rows across all of them curl -X POST "https://motherbot.io/api/v1/messages" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "to": "919876543210", "type": "interactive", "interactive": { "type": "list", "body": { "text": "Pick a slot" }, "action": { "button": "Choose", "sections": [ { "title": "Tomorrow", "rows": [ { "id": "10", "title": "10:00", "description": "45 min" } ] } ] } } }' # URL button curl -X POST "https://motherbot.io/api/v1/messages" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "to": "919876543210", "type": "interactive", "interactive": { "type": "cta_url", "body": { "text": "Your video is ready" }, "action": { "displayText": "Watch it", "url": "https://cdn.example.com/a.mp4" } } }' # Another channel entirely — Telegram (chat id as 'to'), and email curl -X POST "https://motherbot.io/api/v1/messages" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "to": "5551234567", "channel": "telegram", "type": "text", "text": { "body": "Your order has shipped." } }' curl -X POST "https://motherbot.io/api/v1/messages" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "to": "priya@example.com", "channel": "email", "subject": "Your order has shipped", "text": { "body": "Tracking: ABC123" } }' ``` Response: ```json { "success": true, "data": { "messageId": "wamid.HBgNOTE5...", "to": "919876543210", "status": "sent", "channel": "whatsapp", "accountId": "66f1c2a0d3b4e5f6a7b8c9d0", "contactId": "6650f1a2b3c4d5e6f7a8b9c0", "contactCreated": false } } ``` #### POST /api/v1/messages/bulk Bulk send template. Sends a WhatsApp template to up to 100,000 recipients. Each recipient can carry its own body variables, header value and button values. Numbers you have never messaged are added to your contacts automatically; unusable numbers, duplicates and contacts who are blocked or opted out come back as skipped without failing the rest. **Small batches send inline; large batches are queued.** Up to 250 recipients the messages are sent during the request and you get `207` with a per-recipient `results` array, exactly as before. Above that the request is accepted, the work is queued, and you get `202` immediately with a `batchId` — poll `GET /api/v1/messages/bulk/:batchId` for progress. Check the `mode` field (`"sync"` or `"async"`) rather than the status code. This split is not a preference. A 10,000-recipient batch sent inline is several minutes of held-open connection: it ends at a gateway timeout, the messages have already gone, you have no idea which, and retrying — the obvious reaction to a 504 — sends them all again. Queued, the work runs on the same machinery broadcasts use, with per-second pacing against the number's real Meta budget, retries, and an idempotency guard that stops a redelivered job sending twice. Force either path with `mode`. `mode: "sync"` above 250 recipients is refused rather than accepted and timed out. Body parameters: - `templateName` (string, required): Template name exactly as stored (must be APPROVED) - `languageCode` (string, required): Template language code e.g. en_US - `accountId` (string, optional): Which WhatsApp number to send from — an `id` from GET /channels. Defaults to your default number. An account that isn't yours or isn't connected is refused, never swapped; a template that doesn't belong to it is refused too, before the batch runs. - `recipients` (array, required, allowed: 1–100,000 items): Array of recipient objects - `mode` (string, optional, default auto, allowed: auto | sync | async): `auto` sends batches of 250 or fewer inline (207) and queues anything larger (202). `sync` forces the inline path and is refused above 250. `async` queues any size, including a single recipient. - `rateLimitPerSecond` (number, optional, allowed: 1–80): Queued path only — messages per second. Defaults to what this number's Meta messaging tier can safely absorb, which is almost always the right answer; the worker re-checks the real budget before every send regardless. - `recipients[].to` (string, required): Recipient phone number in international format, digits only. Created as a contact if new. - `recipients[].variables` (object, optional): Body variable values keyed by placeholder number ("1", "2", …). Filled to exactly the count the approved template takes — extras are dropped, missing ones sent blank — so a stale mapping can't fail the send. - `recipients[].headerMediaUrl` (string, optional): This recipient's OWN header media — their invoice, their ticket, their product shot. Falls back to the shared `headerVariables` when absent. An unusable link is reported as `skipped` for that recipient with the reason, rather than failing the batch or costing a send. - `recipients[].headerVariables` (string[], optional): The same slot for a TEXT header: this recipient's `{{n}}` values. Falls back to the shared list **per position**, so a two-variable header can have one value that differs per recipient and one fixed for the batch. - `recipients[].buttonVariablesByIndex` (object, optional): This recipient's dynamic URL button values, keyed by the button's real index. - `headerVariables` (string[], optional): Shared header values for all recipients: the media URL for an image/video/document header, or the values for a TEXT header's {{n}}. The template's approved header format decides which. Omit for a media header to reuse the sample it was approved with. Overridden per position by `recipients[].headerVariables`. - `buttonVariables` (string[], optional): One value per dynamic URL button, in the order those buttons appear on the template. Each is placed at that button's real index, so a quick-reply button ahead of it doesn't shift the position. Copy-code, catalogue and carousel templates need nothing here — their parameters are filled from the approved definition. Responses: 202 Accepted and queued — poll `statusUrl` for per-recipient results; 207 Sent inline — check each result's status field; 400 invalid_template — template not APPROVED or not found; 400 `mode: "sync"` above 250 recipients — use the queued path; 429 Bulk rate limit exceeded. Example: ```bash curl -X POST "https://motherbot.io/api/v1/messages/bulk" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "templateName": "order_confirmation", "languageCode": "en_US", "headerVariables": ["https://cdn.mystore.com/banner.jpg"], "buttonVariables": ["https://track.mystore.com/orders/"], "recipients": [ { "to": "919876543210", "variables": { "1": "John", "2": "ORDER-9912", "3": "₹599" } }, { "to": "918765432109", "variables": { "1": "Priya", "2": "ORDER-9913", "3": "₹299" } } ] }' ``` Response: ```json // 250 recipients or fewer — sent inline (HTTP 207) { "success": true, "mode": "sync", "channel": "whatsapp", "accountId": "66f1c2a0d3b4e5f6a7b8c9d0", "summary": { "total": 3, "sent": 2, "failed": 0, "skipped": 1 }, "results": [ { "to": "919876543210", "status": "sent", "messageId": "wamid.AAA..." }, { "to": "918765432109", "status": "sent", "messageId": "wamid.BBB..." }, { "to": "910000000000", "status": "skipped", "error": "Contact has opted out" } ] } // More than 250 — accepted and queued (HTTP 202), back in milliseconds { "success": true, "mode": "async", "channel": "whatsapp", "accountId": "66f1c2a0d3b4e5f6a7b8c9d0", "batchId": "66a2b1c0d3b4e5f6a7b8c9d0", "status": "queued", "statusUrl": "/api/v1/messages/bulk/66a2b1c0d3b4e5f6a7b8c9d0", "summary": { "total": 10000, "queued": 9987, "skipped": 13 }, "results": [ { "to": "910000000000", "status": "skipped", "error": "Contact has opted out" } ], "rateLimitPerSecond": 10, "etaSeconds": 999, "etaText": "~17 minutes" } ``` #### GET /api/v1/messages/bulk/:batchId Bulk send status. How a queued bulk send is getting on: the running totals and every recipient's outcome, including the delivery timestamps the inline path can never report because it answers before WhatsApp has said anything. Poll this with the `batchId` from a `202`. Needs `messages:read` — a key that can send a bulk message can read what happened to it without also holding the broadcast permission. Path parameters: - `batchId` (string, required): The `batchId` returned by POST /api/v1/messages/bulk Query parameters: - `status` (string, optional, allowed: queued | sent | delivered | read | failed): Only recipients in this state — `status=failed` is the one to poll for a retry list - `page` (integer, optional, default 1): Page number - `limit` (integer, optional, default 100, allowed: 1–1000): Recipients per page Responses: 200 Batch status returned; 404 No such batch in this organization. Example: ```bash curl "https://motherbot.io/api/v1/messages/bulk/66a2b1c0d3b4e5f6a7b8c9d0" \ -H "Authorization: Bearer motherbot_xxx" # Just the ones that failed curl "https://motherbot.io/api/v1/messages/bulk/66a2b1c0d3b4e5f6a7b8c9d0?status=failed&limit=1000" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": { "batchId": "66a2b1c0d3b4e5f6a7b8c9d0", "status": "running", "accountId": "66f1c2a0d3b4e5f6a7b8c9d0", "summary": { "total": 9987, "queued": 4102, "sent": 5885, "delivered": 5210, "read": 3840, "failed": 0 }, "rateLimitPerSecond": 10, "etaSeconds": 410, "startedAt": "2026-08-16T09:00:00.000Z", "completedAt": null, "recipients": [ { "to": "919876543210", "name": "Priya Sharma", "status": "read", "messageId": "wamid.AAA...", "sentAt": "2026-08-16T09:00:01.000Z", "deliveredAt": "2026-08-16T09:00:03.000Z", "readAt": "2026-08-16T09:04:11.000Z" } ] }, "pagination": { "page": 1, "limit": 100, "total": 9987, "pages": 100 } } ``` ### Templates #### GET /api/v1/templates List templates. Returns your WhatsApp message templates with optional filtering by status, category, and language. Use this to discover which templates are approved and ready to use in messages or bulk sends. Templates are approved **per WhatsApp number**, and each row carries the `accountId` it belongs to. Pass `accountId` to list only the templates for the number a customer picked — sending a template from a number it wasn't approved on is rejected by Meta, once per recipient. Query parameters: - `accountId` (string, optional): Only templates belonging to this WhatsApp account — an `id` from GET /channels - `status` (string, optional, allowed: APPROVED, PENDING, REJECTED, DISABLED, DRAFT): Filter by Meta approval status - `category` (string, optional, allowed: AUTHENTICATION, MARKETING, UTILITY): Filter by template category - `language` (string, optional): Filter by language code e.g. en_US, hi, ar - `search` (string, optional): Partial match on template name (case-insensitive) - `page` (integer, optional, default 1): Page number - `limit` (integer, optional, default 20, allowed: 1–100): Results per page Example: ```bash curl "https://motherbot.io/api/v1/templates?status=APPROVED&category=MARKETING" \ -H "Authorization: Bearer motherbot_xxx" # Only the templates for one number curl "https://motherbot.io/api/v1/templates?accountId=66f1c2a0d3b4e5f6a7b8c9d0&status=APPROVED" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": [ { "_id": "665b2a...", "accountId": "66f1c2a0d3b4e5f6a7b8c9d0", "metaTemplateId": "1234567890", "name": "order_confirmation", "category": "MARKETING", "language": "en_US", "status": "APPROVED", "variables": ["customer_name", "order_id", "amount"], "usageCount": 4821, "components": [ { "type": "HEADER", "format": "IMAGE" }, { "type": "BODY", "text": "Hi {{1}}, your order {{2}} of {{3}} is confirmed!" }, { "type": "FOOTER", "text": "Reply STOP to unsubscribe" }, { "type": "BUTTONS", "buttons": [{ "type": "URL", "text": "Track Order", "url": "https://mystore.com/track/{{1}}" }] } ], "createdAt": "2026-04-10T08:00:00.000Z", "updatedAt": "2026-06-01T12:00:00.000Z" } ], "pagination": { "page": 1, "limit": 20, "total": 12, "pages": 1 } } ``` ### Broadcasts #### GET /api/v1/campaigns List broadcasts. Returns a paginated list of broadcasts with their delivery stats and template info. Query parameters: - `status` (string, optional, allowed: draft, scheduled, running, paused, completed, failed): Filter by broadcast status - `page` (integer, optional, default 1): Page number - `limit` (integer, optional, default 20, allowed: 1–100): Results per page Example: ```bash curl "https://motherbot.io/api/v1/campaigns?status=completed" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": [ { "_id": "665c3b...", "name": "June Sale Blast", "status": "completed", "audienceType": "all", "audienceCount": 9800, "template": { "_id": "665b2a...", "name": "order_confirmation", "category": "MARKETING" }, "stats": { "total": 9800, "sent": 9750, "delivered": 9600, "read": 7200, "failed": 50, "replied": 320 }, "startedAt": "2026-06-01T09:00:01.000Z", "completedAt": "2026-06-01T09:14:22.000Z" } ], "pagination": { "page": 1, "limit": 20, "total": 1, "pages": 1 } } ``` #### POST /api/v1/campaigns Create broadcast. Creates a new broadcast as a draft or schedules it for a future time. The broadcast is not sent immediately. Only contacts with optedIn: true and blocked: false are counted in the audience. Body parameters: - `name` (string, required): Broadcast display name - `templateId` (string, required): _id of an APPROVED template - `audienceType` (string, optional, default all, allowed: all, tags): Audience selection strategy - `audienceTags` (string[], optional): Required when audienceType is tags - `scheduledAt` (date-time string, optional): When to send. Write it as YYYY-MM-DD HH:MM:SS and it is read in your organisation's timezone (Settings → Organisation) — '2026-09-01 09:00:00' means nine in the morning where your business is. A string ending in Z or an offset is taken as that exact instant instead. Omit to save as a draft. Must be in the future and no more than 90 days ahead. - `description` (string, optional): Internal description Example: ```bash curl -X POST "https://motherbot.io/api/v1/campaigns" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "name": "Diwali Offer 2026", "templateId": "665b2a...", "audienceType": "tags", "audienceTags": ["opted-in", "delhi"], "scheduledAt": "2026-10-20 09:00:00" }' ``` Response: ```json { "success": true, "data": { "_id": "665d4c...", "name": "Diwali Offer 2026", "status": "scheduled", "audienceType": "tags", "audienceTags": ["opted-in", "delhi"], "audienceCount": 3200, "scheduledAt": "2026-10-20T09:00:00.000Z", "stats": { "total": 3200, "sent": 0, "delivered": 0, "read": 0, "failed": 0 }, "createdAt": "2026-06-24T10:30:00.000Z" } } ``` #### POST /api/v1/campaigns/send Broadcast send (inline recipients). Creates and immediately launches a broadcast campaign. Recipients are provided inline — no pre-registration in your contacts list is needed. Use commonVariables for values shared by every recipient; only include per-recipient overrides in recipients[].variables. Merged result per recipient: { ...commonVariables, ...recipient.variables }. Up to 100,000 recipients per request. Duplicate phone numbers are silently deduplicated. The campaign appears in the dashboard with a Source badge of 'API'. Body parameters: - `name` (string, optional): Campaign name — auto-generated from template name and date if omitted - `templateId` (string, optional): Template MongoDB _id (use this or templateName + languageCode) - `templateName` (string, optional): Template name — requires languageCode - `languageCode` (string, optional): Language code e.g. en_US, hi — required when using templateName - `commonVariables` (object, optional): Body variable values shared by all recipients e.g. { "1": "MotherBot", "3": "support@example.com" } - `headerMediaUrl` (string, optional): Public URL for an IMAGE / VIDEO / DOCUMENT header, shared by every recipient. Overridden by `recipients[].headerMediaUrl`. Every link is validated BEFORE any job is queued — one unusable value refuses the whole request naming which recipient, rather than failing 40,000 sends one at a time after the broadcast has started. - `headerVariables` (string[], optional): The same slot for a TEXT header: values for the header's `{{n}}`, shared by every recipient and overridden per position by `recipients[].headerVariables`. A TEXT header used to get no parameter at all from this endpoint, which rejected every recipient with #132000. - `recipients[].headerMediaUrl` (string, optional): This recipient's OWN header media — their invoice or ticket rather than one banner for the whole broadcast. - `recipients[].headerVariables` (string[], optional): This recipient's TEXT header values, falling back per position to the campaign-wide list. - `rateLimitPerSecond` (number, optional, default 3, allowed: 1–80): Messages per second - `accountId` (string, optional): Which WhatsApp number to broadcast from — an `id` from GET /channels. Defaults to your default number. An account that isn't yours or isn't connected is refused, never swapped: a broadcast on the wrong number damages that number's quality rating, and the response would not show it. - `channel` (string, optional, default whatsapp): Accepted for symmetry with POST /messages, but a broadcast sends an approved WhatsApp template — any other channel is refused with `unsupported_for_channel`. Use POST /messages to reach contacts elsewhere. - `recipients` (array, required, allowed: 1–100,000 items): Recipient list — no contact pre-registration needed - `recipients[].to` (string, required): Phone number with country code, no + prefix (e.g. 919876543210) - `recipients[].name` (string, optional): Recipient name stored in the broadcast message log for reporting - `recipients[].variables` (object, optional): Per-recipient variable overrides — merged on top of commonVariables Responses: 201 Broadcast created and running — use campaignId to poll stats; 400 invalid_template — template not found, not APPROVED, or not on the account you chose; 400 no_whatsapp_account — no connected WhatsApp account, or the accountId isn't yours; 400 unsupported_for_channel — broadcasts are WhatsApp templates only; 429 Broadcast rate limit exceeded. Example: ```bash curl -X POST "https://motherbot.io/api/v1/campaigns/send" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "name": "June Order Dispatch", "templateName": "order_confirmation", "languageCode": "en_US", "commonVariables": { "1": "MotherBot Store", "3": "support@mystore.com" }, "headerMediaUrl": "https://cdn.mystore.com/banner.jpg", "rateLimitPerSecond": 10, "recipients": [ { "to": "919876543210", "name": "John Smith", "variables": { "2": "ORDER-9912" } }, { "to": "918765432109", "name": "Priya Sharma", "variables": { "2": "ORDER-9913" } }, { "to": "917654321098", "name": "Ravi Kumar" } ] }' ``` Response: ```json { "success": true, "data": { "campaignId": "665d4c...", "status": "running", "total": 3, "channel": "whatsapp", "accountId": "66f1c2a0d3b4e5f6a7b8c9d0", "rateLimitPerSecond": 10, "etaSeconds": 1, "etaText": "~1 second" } } ``` #### GET /api/v1/campaigns/:id/stats Get broadcast stats. Returns live delivery statistics for a specific broadcast, including source (platform or api), who launched it, and the estimated WhatsApp cost. billableCount = messages Meta charged for (each sent message counted once, whatever its later delivery status); freeCount = messages Meta didn't charge for. estimatedCost prices each message at the category Meta billed it under, using your rate card. A free-form broadcast is priced at the reply (service) rate — Meta doesn't charge for the first 1,000 replies each month on each WhatsApp number. Path parameters: - `id` (string, required): Broadcast _id Example: ```bash curl "https://motherbot.io/api/v1/campaigns/665c3b.../stats" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": { "_id": "665c3b...", "name": "June Sale Blast", "status": "completed", "source": "api", "audienceCount": 9800, "stats": { "total": 9800, "queued": 0, "sent": 9750, "delivered": 9600, "read": 7200, "failed": 50, "replied": 320, "clicked": 480, "optedOut": 12 }, "cost": { "pricePerConversation": 0.78, "billableCount": 9750, "estimatedCost": 7605.00, "currency": "INR", "templateCategory": "MARKETING", "freeCount": 0 }, "startedAt": "2026-06-01T09:00:01.000Z", "completedAt": "2026-06-01T09:14:22.000Z" } } ``` #### POST /api/v1/campaigns/:id/pause Pause broadcast. Pauses a broadcast that is currently running or scheduled. Returns 400 invalid_state if the broadcast is in any other status. Path parameters: - `id` (string, required): Broadcast _id Responses: 200 Broadcast paused; 400 invalid_state — broadcast is not running or scheduled. Example: ```bash curl -X POST "https://motherbot.io/api/v1/campaigns/665c3b.../pause" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": { "id": "665c3b...", "status": "paused" } } ``` #### POST /api/v1/campaigns/:id/resume Resume broadcast. Resumes a paused campaign. Returns 400 invalid_state if the campaign is not in paused status. Path parameters: - `id` (string, required): Broadcast _id Responses: 200 Broadcast resumed; 400 invalid_state — broadcast is not paused. Example: ```bash curl -X POST "https://motherbot.io/api/v1/campaigns/665c3b.../resume" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": { "id": "665c3b...", "status": "running" } } ``` ### Segments #### GET /api/v1/segments List saved segments. A segment stores RULES, never a member list, so it re-evaluates every time it is used. Use a segment's id as segmentId when launching a broadcast, enrolling a sequence, or sending a coupon. Query parameters: - `count` (string, optional, allowed: 1): Pass 1 to also resolve each segment's current size (one count query per segment) Example: ```bash curl "https://motherbot.io/api/v1/segments?count=1" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": [ { "id": "6651a...", "name": "Lapsed buyers", "description": "No order in 90 days", "match": "all", "ruleCount": 3, "count": 412, "updatedAt": "2026-07-20T11:02:00.000Z" } ] } ``` ### Sequences #### GET /api/v1/sequences List sequences. Every drip sequence with its step count, entry rule and stats. Example: ```bash curl "https://motherbot.io/api/v1/sequences" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": [ { "id": "6653d...", "name": "Trial nudges", "status": "active", "stepCount": 3, "stats": { "enrolled": 420, "completed": 180, "exited": 60, "sent": 940, "failed": 2 } } ] } ``` #### POST /api/v1/sequences Create a sequence. Always created as a DRAFT — activate it from the dashboard once the steps look right, so an API typo can never start messaging customers immediately. Every {{n}} in a step's template must appear in templateVariableMapping, or Meta rejects the send. Body parameters: - `name` (string, required): Sequence name - `whatsappAccountId` (string, required): Number the sequence sends from - `entry` (object, optional): { type: "manual" | "segment" | "tags" | "ad", segmentId?, tags?, adSourceId? } - `steps` (array, required): Up to 20 steps: { templateId, delayValue, delayUnit, templateVariableMapping, headerMediaUrl? } - `stopOnReply` (boolean, optional, default true): Exit the sequence the moment the customer replies Responses: 201 Sequence created as a draft; 400 invalid_request — unapproved template, bad delay, or >20 steps. Example: ```bash curl -X POST "https://motherbot.io/api/v1/sequences" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "name": "Trial nudges", "whatsappAccountId": "6640a...", "entry": { "type": "manual" }, "steps": [ { "templateId": "6642b...", "delayValue": 0, "delayUnit": "minutes", "templateVariableMapping": { "1": "{{contact.firstName}}" } }, { "templateId": "6642c...", "delayValue": 2, "delayUnit": "days", "templateVariableMapping": { "1": "{{contact.firstName}}", "2": "TRIAL20" } } ], "stopOnReply": true }' ``` Response: ```json { "success": true, "data": { "id": "6653d...", "status": "draft" } } ``` #### POST /api/v1/sequences/:id/enroll Enroll contacts. Pass exactly one selector. Only opted-in, non-blocked contacts are enrolled and anyone already in the sequence is skipped — so calling this repeatedly from an automation is safe. Path parameters: - `id` (string, required): Sequence ID Body parameters: - `tag` (string, optional): Everyone carrying this tag - `segmentId` (string, optional): Everyone in this saved segment - `contactIds` (array, optional): Explicit contact IDs Example: ```bash curl -X POST "https://motherbot.io/api/v1/sequences/6653d.../enroll" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "tag": "trial" }' ``` Response: ```json { "success": true, "data": { "enrolled": 128, "skipped": 12 } } ``` #### GET /api/v1/sequences/:id/enrollments Per-recipient progress. Who is in the sequence, which step they are on, what sent and what failed — the detail the stats summary cannot give you. Path parameters: - `id` (string, required): Sequence ID Query parameters: - `status` (string, optional, allowed: active | completed | exited | failed): Filter by enrollment status Example: ```bash curl "https://motherbot.io/api/v1/sequences/6653d.../enrollments?status=failed" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": { "totalSteps": 3, "rows": [ { "contactId": "6650...", "name": "Priya", "phone": "+919876543210", "status": "active", "step": 2, "totalSteps": 3, "sentCount": 1, "nextRunAt": "2026-07-25T09:00:00.000Z" } ] } } ``` ### Appointments #### GET /api/v1/appointments List appointments. Bookings, newest slot first. Everything the calendar holds — taken in chat, by your team, in the phone app, or through this API. Query parameters: - `status` (string, optional, allowed: pending | confirmed | cancelled | completed | no_show): Comma-separated. Omit for every status. - `from` (string, optional): Earliest date, YYYY-MM-DD in your timezone (inclusive) - `to` (string, optional): Latest date, YYYY-MM-DD in your timezone (inclusive) - `serviceId` (string, optional): Only bookings for this service - `resourceId` (string, optional): Only bookings with this staff member or resource. Pass `none` for unassigned ones. - `contactId` (string, optional): Only this customer's bookings - `source` (string, optional, allowed: chatbot | dashboard | api | flow | workflow | mobile): Where the booking was made - `search` (string, optional): Name, phone, email, service, staff, or the booking reference - `sortBy` (string, optional, default startsAt, allowed: startsAt | createdAt | name | status | service | resource): Sort column - `sortDir` (string, optional, default asc, allowed: asc | desc): Sort direction - `page` (integer, optional, default 1): Page number - `limit` (integer, optional, default 25, allowed: 1-100): Rows per page. Max 100. Example: ```bash curl "https://motherbot.io/api/v1/appointments?from=2026-08-01&status=confirmed" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": [ { "id": "6660b...", "code": "K7M2QX9P", "status": "confirmed", "date": "2026-08-03", "time": "10:30", "endTime": "11:00", "dateLabel": "Mon, 3 Aug 2026", "timeLabel": "10:30", "startsAt": "2026-08-03T05:00:00.000Z", "timezone": "Asia/Kolkata", "duration": 30, "service": { "id": "6660c...", "name": "Consultation" }, "resource": { "id": "6660d...", "name": "Dr. Mehta" }, "contact": { "id": "664a1...", "name": "Rahul Sharma", "phone": "919876543210" }, "name": "Rahul Sharma", "phone": "+919876543210", "partySize": 1, "source": "chatbot" } ], "pagination": { "page": 1, "limit": 25, "total": 42, "pages": 2 } } ``` #### POST /api/v1/appointments Book an appointment. Books a slot for a contact. The slot is re-checked against opening hours, staff, capacity and buffers inside a lock, so two calls racing for the last seat cannot both win — the loser gets 409. Your notice period and booking window don't apply to API calls (you are the business); `force: true` additionally ignores hours and capacity, for a walk-in. Send an `Idempotency-Key` header and a retry returns the SAME booking instead of a second one. Body parameters: - `contactId` (string, required): Who the booking is for - `date` (string, optional): YYYY-MM-DD in your timezone. Required unless `start` is given. - `time` (string, optional): HH:MM, 24-hour, in your timezone. Required unless `start` is given. - `start` (string, optional): ISO 8601 instant, instead of date + time - `serviceId` (string, optional): Sets the length, seats and price - `resourceId` (string, optional): A specific staff member or resource. Omit to let the calendar pick whoever is free. - `partySize` (integer, optional, default 1): Seats taken — a table, a class booking - `name` (string, optional): Defaults to the contact's name - `phone` (string, optional): Defaults to the contact's number - `email` (string, optional): Emailed confirmations and your own records - `notes` (string, optional): Shown to the customer - `staffNotes` (string, optional): Internal only — never sent to the customer - `status` (string, optional, default confirmed, allowed: pending | confirmed): `pending` puts it in your approval queue while still holding the slot - `force` (boolean, optional, default false): Book outside hours and past capacity - `notifyCustomer` (boolean, optional): Send the confirmation message. Defaults to your Appointments setting. - `idempotencyKey` (string, optional): Same as the `Idempotency-Key` header; the header wins if both are sent. Responses: 201 Booked; 200 Replayed — this Idempotency-Key already booked something; 409 full / daily_cap / limit_reached — the slot or day is taken; 422 outside_hours, too_soon, past, service_unavailable, resource_unavailable; 503 busy — the calendar was locked by another booking; retry. Example: ```bash curl -X POST "https://motherbot.io/api/v1/appointments" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Idempotency-Key: booking-4417" \ -H "Content-Type: application/json" \ -d '{ "contactId": "664a1f88c2b19d0012ab0001", "date": "2026-08-03", "time": "10:30", "serviceId": "6660c0a1c2b19d0012ab0b01" }' ``` Response: ```json { "success": true, "data": { "id": "6660b...", "code": "K7M2QX9P", "status": "confirmed", "date": "2026-08-03", "time": "10:30", "duration": 30 }, "replayed": false, "customerNotified": true } ``` #### GET /api/v1/appointments/:id Get one appointment. The full booking, its reminders and which statuses it may move to next. Path parameters: - `id` (string, required): Appointment ID Example: ```bash curl "https://motherbot.io/api/v1/appointments/6660b0a1c2b19d0012ab0a01" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": { "id": "6660b...", "code": "K7M2QX9P", "status": "confirmed", "date": "2026-08-03", "reminders": [{ "key": "r1", "dueAt": "2026-08-02T05:00:00.000Z", "sentAt": null, "skipReason": null }] }, "allowedStatuses": ["pending", "completed", "no_show", "cancelled"] } ``` #### PATCH /api/v1/appointments/:id Update details or status. Change the customer's details, your internal notes, or the status. Moving the time has its own endpoint, and so does cancelling. Marking a booking `confirmed` from `pending` sends the approval message. Path parameters: - `id` (string, required): Appointment ID Body parameters: - `status` (string, optional, allowed: pending | confirmed | completed | no_show | cancelled): Only moves the booking is allowed to make — a completed booking can't go back to pending. `cancelled` behaves exactly like the cancel endpoint. - `name` (string, optional): Customer name on the booking - `phone` (string, optional): Contact number on the booking - `email` (string, optional): Email on the booking - `notes` (string, optional): Shown to the customer - `staffNotes` (string, optional): Internal only - `location` (string, optional): Where it happens - `reason` (string, optional): Recorded in the booking's history with the status change - `notifyCustomer` (boolean, optional): Override your Appointments setting for this change - `force` (boolean, optional): When reopening a cancelled booking, take the slot even if it has been resold Responses: 200 Updated; 409 invalid_transition — that status change isn't allowed from where it is. Example: ```bash curl -X PATCH "https://motherbot.io/api/v1/appointments/6660b0a1c2b19d0012ab0a01" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "status": "completed" }' ``` Response: ```json { "success": true, "data": { "id": "6660b...", "status": "completed" }, "customerNotified": false } ``` #### POST /api/v1/appointments/:id/reschedule Move an appointment. Moves the booking to a new time, optionally to a different staff member or service. The reference stays the same, reminders are re-timed for the new time, and the new slot is checked exactly as a fresh booking is. Path parameters: - `id` (string, required): Appointment ID Body parameters: - `date` (string, optional): YYYY-MM-DD. Required unless `start` is given. - `time` (string, optional): HH:MM, 24-hour. Required unless `start` is given. - `start` (string, optional): ISO 8601 instant, instead of date + time - `resourceId` (string, optional): Move it to somebody else. Send null to clear. - `serviceId` (string, optional): Change the service too. Send null to clear. - `force` (boolean, optional, default false): Ignore hours and capacity - `notifyCustomer` (boolean, optional): Send the “moved” message - `note` (string, optional): Recorded in the booking's history Responses: 200 Moved; 409 full / unchanged / not_active; 422 outside_hours, past, resource_unavailable. Example: ```bash curl -X POST "https://motherbot.io/api/v1/appointments/6660b0a1c2b19d0012ab0a01/reschedule" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "date": "2026-08-05", "time": "16:00" }' ``` Response: ```json { "success": true, "data": { "id": "6660b...", "date": "2026-08-05", "time": "16:00", "rescheduleCount": 1 }, "customerNotified": true } ``` #### POST /api/v1/appointments/:id/cancel Cancel an appointment. Frees the slot and stops its reminders. The booking is kept as a cancelled record, so your reports still see it. Path parameters: - `id` (string, required): Appointment ID Body parameters: - `reason` (string, optional): Stored on the booking and available to the cancellation message - `notifyCustomer` (boolean, optional): Send the cancellation message Responses: 200 Cancelled; 409 not_active — it was already cancelled or closed. Example: ```bash curl -X POST "https://motherbot.io/api/v1/appointments/6660b0a1c2b19d0012ab0a01/cancel" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "reason": "Customer called to cancel" }' ``` Response: ```json { "success": true, "data": { "id": "6660b...", "status": "cancelled" }, "customerNotified": true } ``` #### GET /api/v1/appointments/availability What's free. With `date`, the bookable start times on that day and its named shifts. Without, the dates in range that still have room. This is the same availability the chatbot offers, so anything it returns can actually be booked. Query parameters: - `date` (string, optional): YYYY-MM-DD — returns that day's slots instead of a list of dates - `from` (string, optional): First date to look at (defaults to today) - `to` (string, optional): Last date to look at (defaults to the end of your booking window) - `serviceId` (string, optional): Use this service's length, seats and staff - `resourceId` (string, optional): Only this staff member's or resource's calendar - `partySize` (integer, optional, default 1): Seats needed - `shift` (string, optional): Only slots in this named session, e.g. Morning - `excludeAppointmentId` (string, optional): Ignore this booking's own seat — use when offering times for a reschedule - `customerView` (boolean, optional, default false): Apply the notice period and booking window a customer gets. Use this when the answer feeds your own booking page. - `limit` (integer, optional, default 60, allowed: 1-120): How many dates to return. Max 120. Example: ```bash curl "https://motherbot.io/api/v1/appointments/availability?date=2026-08-03&serviceId=6660c0a1c2b19d0012ab0b01" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": { "date": "2026-08-03", "slots": [ { "time": "10:30", "label": "10:30", "endTime": "11:00", "start": "2026-08-03T05:00:00.000Z", "seatsLeft": 1, "resources": [{ "id": "6660d...", "name": "Dr. Mehta", "seatsLeft": 1 }] } ], "shifts": [{ "value": "Morning", "label": "Morning" }] } } ``` #### GET /api/v1/appointments/services List services. What customers can book, with the length, seats, price and which staff deliver each one. Example: ```bash curl "https://motherbot.io/api/v1/appointments/services" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": [ { "id": "6660c...", "name": "Consultation", "duration": 30, "bufferAfter": null, "capacity": null, "maxPartySize": 1, "price": 500, "currency": "INR", "resourceIds": ["6660d..."], "locationType": "in_person", "isActive": true } ] } ``` #### GET /api/v1/appointments/resources List staff & resources. The people, rooms and equipment bookings are made with. Each keeps its own calendar. Query parameters: - `serviceId` (string, optional): Only the ones that deliver this service Example: ```bash curl "https://motherbot.io/api/v1/appointments/resources" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": [ { "id": "6660d...", "name": "Dr. Mehta", "kind": "person", "capacity": 1, "isActive": true } ] } ``` ### Coupons #### GET /api/v1/coupons List coupons. Every coupon with its issued and redeemed counts. Example: ```bash curl "https://motherbot.io/api/v1/coupons" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": [ { "_id": "6654e...", "name": "Diwali 25", "kind": "shared", "code": "DIWALI25", "discountType": "percent", "discountValue": 25, "issuedCount": 380, "redeemedCount": 112, "isActive": true } ] } ``` #### POST /api/v1/coupons Create a coupon. A "shared" coupon is one code everyone gets (needs code). A "unique" coupon mints a distinct code per person on issue — the only way a one-use-each promise is actually enforceable. Body parameters: - `name` (string, required): Internal name (unique per org) - `kind` (string, optional, default shared, allowed: shared | unique): One code for all, or one per person - `code` (string, optional): Required when kind is shared - `discountType` (string, optional, default percent, allowed: percent | amount | free_shipping | custom): Discount shape - `discountValue` (number, optional): 20 for 20% or ₹20 - `expiresAt` (string, optional): ISO date - `maxRedemptions` (integer, optional, default 0): Total allowed across everyone (0 = unlimited) - `maxPerContact` (integer, optional, default 1): Redemptions allowed per contact Responses: 201 Coupon created; 409 duplicate — a coupon with that name or code already exists. Example: ```bash curl -X POST "https://motherbot.io/api/v1/coupons" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "name": "Diwali 25", "kind": "shared", "code": "DIWALI25", "discountType": "percent", "discountValue": 25, "maxPerContact": 1 }' ``` Response: ```json { "success": true, "data": { "id": "6654e...", "name": "Diwali 25", "kind": "shared", "code": "DIWALI25" } } ``` #### POST /api/v1/coupons/:id/send Issue & send over WhatsApp. Issues the coupon to an audience AND delivers it. It must travel inside an approved template — nothing else clears the 24-hour window for a promotional send — so name the template and which variable carries the code. Uses the broadcast rate-limit bucket (1/10th of your plan limit per call). Path parameters: - `id` (string, required): Coupon ID Body parameters: - `contactIds` (string[], optional): Audience — explicit contact IDs. Pass exactly one of contactIds, tag or segmentId. - `tag` (string, optional): Audience — every contact carrying this tag. Pass exactly one of contactIds, tag or segmentId. - `segmentId` (string, optional): Audience — every contact in this segment. Pass exactly one of contactIds, tag or segmentId. - `templateName` (string, required): An APPROVED template with at least one variable - `templateLanguage` (string, optional, default the template's own language): Language code to send the template in, when it is approved in more than one. - `codeVarIndex` (integer, required): Which {{n}} receives the coupon code - `variables` (object, optional): Values for the template's OTHER variables, e.g. { "1": "{{contact.firstName}}" } - `whatsappAccountId` (string, optional): Number to send from (defaults to your primary) - `headerMediaUrl` (string, optional): Required when the template's header is an image, video or document — the public URL to put in it. Named only in prose before this. Example: ```bash curl -X POST "https://motherbot.io/api/v1/coupons/6654e.../send" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "segmentId": "6651a...", "templateName": "diwali_offer", "codeVarIndex": 2, "variables": { "1": "{{contact.firstName}}" } }' ``` Response: ```json { "success": true, "data": { "sent": 380, "failed": 2, "skipped": 0, "total": 382 } } ``` #### POST /api/v1/coupons/:id/sync Push the code to the store (or pull it back). Creates the coupon inside the connected Shopify or WooCommerce store so it actually discounts at checkout. Idempotent — a coupon already in the store answers without touching it — so this is what you call after fixing whatever the store objected to. Removing a `unique` coupon's codes is bounded per call; the response reports `remaining`, call again to continue. Path parameters: - `id` (string, required): Coupon ID Body parameters: - `action` (string, optional, default sync, allowed: sync | remove): Put the code into the store, or take it out Example: ```bash curl -X POST "https://motherbot.io/api/v1/coupons/6654e.../sync" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "action": "sync" }' ``` Response: ```json { "success": true, "data": { "externalId": "gid://shopify/DiscountCodeNode/14...", "code": "DIWALI25", "adopted": false } } ``` #### GET /api/v1/coupons/:id/redemptions List redemptions. The orders behind the counters — order number, order value, who redeemed, and whether it came from a store checkout, the API, or a person at a till. That is the difference between "47 redemptions" and knowing whether the promotion paid for itself. Newest first. Path parameters: - `id` (string, required): Coupon ID Query parameters: - `limit` (integer, optional, default 100, allowed: 1–500): How many redemptions to return Example: ```bash curl "https://motherbot.io/api/v1/coupons/6654e.../redemptions?limit=200" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": [ { "_id": "6712aa...", "code": "DIWALI25", "reference": "order_10482", "orderNumber": "#10482", "source": "shopify", "amount": 2499, "currency": "INR", "contactId": "664a1f...", "contactName": "Priya Sharma", "waId": "919876543210", "redeemedAt": "2026-07-11T14:20:31.000Z" } ] } ``` #### POST /api/v1/coupons/redeem Redeem (or issue) a code. THE single place expiry, the global cap and the per-contact cap are enforced, so a storefront can call this and trust the answer. Pass contactId — without it a shared code's per-customer limit cannot be enforced. Use action:"issue" to hand a coupon to one contact without sending it. Body parameters: - `code` (string, required): The code the customer entered (omit when action is issue) - `contactId` (string, optional): Who is redeeming — required for per-contact limits to mean anything - `reference` (string, optional): Your order id, stored on the redemption - `action` (string, optional, allowed: issue): Set to "issue" with couponId + contactId + waId to mint a code without sending it - `couponId` (string, optional): The coupon to mint from. Required when action is "issue"; ignored otherwise. - `waId` (string, optional): The recipient's WhatsApp id, in international format. Required when action is "issue". Responses: 200 Redeemed; 400 invalid_request — expired, already used, or cap reached. Example: ```bash curl -X POST "https://motherbot.io/api/v1/coupons/redeem" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "code": "DIWALI25", "contactId": "6650...", "reference": "order_10482" }' ``` Response: ```json { "success": true, "data": { "couponId": "6654e...", "discountType": "percent", "discountValue": 25 } } ``` ### Links & QR #### GET /api/v1/links List trackable links. Every link with clicks, unique clicks and — for WhatsApp links — how many actually started a chat. Clicks flatter; chats are the number worth reporting. Example: ```bash curl "https://motherbot.io/api/v1/links" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": [ { "_id": "6655f...", "name": "Diwali poster", "kind": "whatsapp", "url": "https://motherbot.io/r/diwali-poster-a7k2", "refCode": "A7K2", "clicks": 1840, "uniqueClicks": 1502, "conversations": 311, "isActive": true } ] } ``` #### POST /api/v1/links Create a trackable link. kind "whatsapp" opens a chat with one of your numbers and prefills a hidden ref code so the resulting CHAT is attributed; kind "url" is a plain trackable short link. A print-ready QR for any link is at /api/growth/links/:id/qr?size=1024. Body parameters: - `name` (string, required): Where you're publishing it, e.g. "Diwali poster" - `kind` (string, optional, default whatsapp, allowed: whatsapp | url): Opens a WhatsApp chat, or redirects to a URL - `whatsappAccountId` (string, optional): Required when kind is whatsapp - `prefillText` (string, optional): The first message the customer sends (they can edit it) - `destinationUrl` (string, optional): Required when kind is url - `utm` (object, optional): { source, medium, broadcast, content, term } appended to destinationUrl Example: ```bash curl -X POST "https://motherbot.io/api/v1/links" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "name": "Diwali poster", "kind": "whatsapp", "whatsappAccountId": "6640a...", "prefillText": "Hi! I saw the Diwali poster." }' ``` Response: ```json { "success": true, "data": { "_id": "6655f...", "slug": "diwali-poster-a7k2", "url": "https://motherbot.io/r/diwali-poster-a7k2", "refCode": "A7K2" } } ``` ### Sales Pipeline (needs the "salesPipeline" plan permission) #### GET /api/v1/pipelines List sales boards and their stages. Stage keys are per-organisation — renaming a stage in the dashboard changes what a valid `stage` value is. Read them here rather than hard-coding them. Example: ```bash curl "https://motherbot.io/api/v1/pipelines" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": [ { "id": "66f0a...", "name": "Sales", "currency": "INR", "isDefault": true, "stages": [ { "key": "new", "name": "New", "order": 0, "isWon": false, "isLost": false }, { "key": "won", "name": "Won", "order": 4, "isWon": true, "isLost": false } ] } ] } ``` #### GET /api/v1/deals List deals. A flat, filtered list rather than the dashboard's board — an integration wants rows to sync, not columns to draw. Query parameters: - `pipelineId` (string, optional): Only deals on this board - `stage` (string, optional): Stage key from GET /pipelines - `status` (string, optional, allowed: open | won | lost): Filter by outcome - `contactId` (string, optional): Every deal for one contact - `ownerId` (string, optional): Deals owned by one team member - `page` (integer, optional, default 1): Page number - `limit` (integer, optional, default 20): Max 100 Example: ```bash curl "https://motherbot.io/api/v1/deals?status=open&limit=50" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": [ { "id": "670c1...", "title": "Bulk order — 200 units", "value": 48000, "currency": "INR", "pipelineId": "66f0a...", "stage": "qualified", "status": "open", "contact": { "id": "664a1...", "name": "Asha Patel", "waId": "919406537037" }, "ageInStage": 3 } ], "pagination": { "page": 1, "limit": 50, "total": 12, "pages": 1 } } ``` #### POST /api/v1/deals Open a deal. A deal always belongs to a contact. Omit `stage` and it lands in the first stage — which is what a new enquiry is. An unknown stage key is a 400 that lists the valid ones rather than silently using the default. Body parameters: - `contactId` (string, required): The contact this deal is for - `title` (string, optional): Defaults to the contact's name - `value` (number, optional): Deal value - `currency` (string, optional): Defaults to the pipeline's currency - `pipelineId` (string, optional): Defaults to your default board - `stage` (string, optional): Stage key; defaults to the first stage - `ownerId` (string, optional): Team member who owns it - `expectedCloseAt` (string, optional): ISO date - `notes` (string, optional): Free text - `source` (string, optional, default api): Where the deal came from — stored on the record and shown in Pipeline reporting. Example: ```bash curl -X POST "https://motherbot.io/api/v1/deals" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "contactId": "664a1...", "title": "Bulk order — 200 units", "value": 48000, "stage": "qualified" }' ``` Response: ```json { "success": true, "data": { "id": "670c1...", "stage": "qualified", "status": "open" } } ``` #### GET /api/v1/deals/:id Get a deal. One deal with its contact and owner resolved to names, so a card can be rendered without a second lookup. Path parameters: - `id` (string, required): Deal ID Responses: 200 OK; 404 not_found — no such deal in your organization. Example: ```bash curl "https://motherbot.io/api/v1/deals/670c11..." \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": { "id": "670c11...", "title": "Bulk order — 200 units", "value": 48000, "currency": "INR", "stage": "qualified", "status": "open", "contactId": "664a1f...", "contactName": "Priya Sharma", "ownerName": "Ankit", "expectedCloseAt": "2026-08-15T00:00:00.000Z", "updatedAt": "2026-07-20T11:02:00.000Z" } } ``` #### PATCH /api/v1/deals/:id Update, move or close a deal. `stage` moves the card — landing in a Won or Lost column sets the status and close date, and moving back out reopens it. `status` does the reverse: it closes the deal AND moves it to the matching column, so a won deal is never left sitting in Negotiation. Path parameters: - `id` (string, required): Deal ID Body parameters: - `stage` (string, optional): Move the card to this stage - `status` (string, optional, allowed: open | won | lost): Close or reopen the deal - `lostReason` (string, optional): Why it was lost - `title` (string, optional): Rename - `value` (number, optional): New value - `ownerId` (string, optional): Reassign - `expectedCloseAt` (string, optional): ISO date - `notes` (string, optional): Free text - `currency` (string, optional): ISO 4217 code for the deal's value, e.g. INR, USD. Example: ```bash curl -X PATCH "https://motherbot.io/api/v1/deals/670c11..." \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "status": "won" }' ``` Response: ```json { "success": true, "data": { "id": "670c1...", "stage": "won", "status": "won" } } ``` #### DELETE /api/v1/deals/:id Delete a deal. Removes the deal permanently. To take a card off the board without losing the history, close it with `status: "lost"` instead. Path parameters: - `id` (string, required): Deal ID Example: ```bash curl -X DELETE "https://motherbot.io/api/v1/deals/670c11..." \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": { "id": "670c11...", "deleted": true } } ``` ### Products #### GET /api/v1/products List catalogue products. Your WhatsApp catalogue, filterable by search term, category, status and stock. Query parameters: - `search` (string, optional): Matches name, SKU or retailer ID - `category` (string, optional): Exact category match - `status` (string, optional, allowed: active | inactive): Listing status - `inStock` (boolean, optional): true or false - `page` (integer, optional, default 1): Page number - `limit` (integer, optional, default 20): Max 100 Example: ```bash curl "https://motherbot.io/api/v1/products?inStock=true" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": [ { "id": "670d4...", "name": "Cotton Kurta", "retailerId": "SKU-1182", "price": 1299, "currency": "INR", "inStock": true, "metaProductId": "78214..." } ], "pagination": { "page": 1, "limit": 20, "total": 84, "pages": 5 } } ``` #### POST /api/v1/products Add a product. Validated for Meta and pushed to your connected catalogue, exactly as from the dashboard. `retailerId` is your own id for the item and is unique per organisation — re-posting the same one returns 409 rather than duplicating it. A failed Meta sync is reported in `metaSync`, not fatal: the product is saved either way. Body parameters: - `name` (string, required): Product name - `retailerId` (string, required): Your own unique id for this item - `price` (number, required): Price in major units (e.g. 1299 = ₹1,299) - `salePrice` (number, optional): Must not exceed price - `currency` (string, optional, default INR): ISO currency code - `description` (string, optional): Shown in the catalogue - `imageUrl` (string, optional): Public image URL — must be a JPG or PNG, the only formats Meta's catalogue accepts (WebP, AVIF, HEIC and GIF are rejected). See POST /media - `url` (string, optional): Product page on your site - `sku` (string, optional): Stock keeping unit - `category` (string, optional): Category name - `brand` (string, optional): Brand name - `whatsappAccount` (string, optional): Which connected WhatsApp number's catalogue this product belongs to. Defaults to your primary. - `status` (string, optional, allowed: active | inactive): Listing status - `inStock` (boolean, optional, default true): Keep this current — it's what stops a chatbot offering something sold out Responses: 201 Created; 402 Product limit reached on your plan; 409 That retailerId already exists. Example: ```bash curl -X POST "https://motherbot.io/api/v1/products" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "name": "Cotton Kurta", "retailerId": "SKU-1182", "price": 1299, "inStock": true }' ``` Response: ```json { "success": true, "data": { "id": "670d4...", "retailerId": "SKU-1182", "metaProductId": null }, "metaSync": { "synced": false, "error": "No catalogue configured" } } ``` #### GET /api/v1/products/:id Get a product. One catalogue row. `metaProductId` is the field worth reading — a product Meta doesn't have cannot be sent in a product message, and that is otherwise an unanswerable "why didn't it send". Path parameters: - `id` (string, required): Product ID Example: ```bash curl "https://motherbot.io/api/v1/products/670d4a..." \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": { "id": "670d4a...", "name": "Cotton Kurta", "retailerId": "SKU-1182", "price": 1299, "salePrice": null, "currency": "INR", "inStock": true, "status": "active", "metaProductId": "7712994...", "updatedAt": "2026-07-02T06:41:00.000Z" } } ``` #### PATCH /api/v1/products/:id Update a product and re-sync to Meta. The endpoint a store keeps pointed at its own price and stock changes. A catalogue that drifts from the shop is worse than no catalogue — the chatbot quotes prices that no longer exist. Path parameters: - `id` (string, required): Product ID Example: ```bash curl -X PATCH "https://motherbot.io/api/v1/products/670d4a..." \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "price": 1149, "inStock": false }' ``` Response: ```json { "success": true, "data": { "id": "670d4...", "price": 1149, "inStock": false }, "metaSync": { "synced": true } } ``` #### DELETE /api/v1/products/:id Delete a product. Removes it here and from the connected Meta catalogue. Path parameters: - `id` (string, required): Product ID Example: ```bash curl -X DELETE "https://motherbot.io/api/v1/products/670d4a..." \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": { "id": "670d4a...", "deleted": true } } ``` ### Media #### POST /api/v1/media Upload a file, get a public URL. The missing rung: POST /messages takes a media link, so without this you'd have to host every image and PDF publicly yourself before you could send it. Multipart, 8 MB max, rate-limited to a tenth of your plan's per-minute allowance. File contents are checked against the declared type — an executable renamed .png is refused. Body parameters: - `file` (file, required): multipart/form-data. JPEG, PNG, MP4, 3GP, MP3, OGG, AAC, PDF, DOC(X), XLS(X), PPTX, TXT, CSV Responses: 201 Uploaded — `mediaType` is the message type to send it as; 413 File over 8 MB; 415 Unsupported type, or contents don't match it. Example: ```bash curl -X POST "https://motherbot.io/api/v1/media" \ -H "Authorization: Bearer motherbot_xxx" \ -F "file=@invoice.pdf" ``` Response: ```json { "success": true, "data": { "url": "https://cdn.motherbot.io/.../invoice.pdf", "mediaType": "document", "mimeType": "application/pdf", "filename": "invoice.pdf", "bytes": 148213, "storage": "s3" } } ``` ### Number Health (needs the "numberHealthGuardian" plan permission) #### GET /api/v1/number-health Health of every connected number. Quality rating, the 24-hour allowance and what's left of it, seven-day delivery/block/opt-out rates, warm-up state, and whether Guardian has paused sending. Read this before a bulk run — a paused number rejects sends, and `remainingToday` decides whether a broadcast finishes or stalls halfway. `dailyCap` and `remainingToday` are `null` on a number Meta has granted an unlimited tier: there is no cap to count down from. Treat null as "no limit", not as zero. The three `sevenDay` rates are 0–1 fractions, and every one of them is a share of `sevenDay.ruledOn` — the messages Meta returned a verdict on (`delivered + failed`). That is deliberately not `sevenDay.sent`: sent counts only broadcast, sequence and template-retry traffic, while the delivery statuses arrive for every message the number sends, so dividing by sent produced rates above 100%. Messages still in flight are in neither term, so the rates stay meaningful mid-broadcast. `protectionEnabled` says whether any of this is actually ENFORCED. When it is `false` the organisation has switched number protection off, so `dailyCap`, `warmup` and `sendingPaused` describe what the number can safely do rather than what it will be held to — the cap is still the figure to pace against, but nothing on our side will stop a send going past it. See `PUT /api/v1/number-health/guard`. Example: ```bash curl "https://motherbot.io/api/v1/number-health" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": [ { "accountId": "66aa1...", "phoneNumber": "+91 94065 37037", "status": "connected", "health": { "score": 78, "level": "caution", "qualityRating": "YELLOW", "dailyCap": 10000, "usedToday": 2140, "remainingToday": 7860, "sevenDay": { "sent": 9310, "delivered": 8994, "failed": 305, "ruledOn": 9299, "deliveryRate": 0.967, "blockRate": 0.0023, "optOutRate": 0.0004 }, "sendingPaused": null, "protectionEnabled": true, "factors": ["Meta has rated this number YELLOW …"] } } ] } ``` ### Number Protection #### GET /api/v1/number-health/guard Is number protection on?. Whether MotherBot is currently allowed to hold your sends back to protect your WhatsApp numbers. Covers the whole organisation, not one number. `enabled: true` is the default for every account and means all of the following apply: the 24-hour cap for each number's messaging tier, the warm-up ramp on a new number, the safe per-second send pace, the circuit breaker that pauses a broadcast when Meta starts withholding it, and the pre-flight that refuses a risky launch. Example: ```bash curl "https://motherbot.io/api/v1/number-health/guard" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": { "enabled": true, "updatedAt": null, "updatedBy": null } } ``` #### PUT /api/v1/number-health/guard Turn number protection on or off. Turns every one of Guardian's stops off — or back on — for the whole organisation. There is ONE switch, not one per integration: setting it here also sets it for the dashboard, the mobile app, the Chrome and spreadsheet extensions, Zoho, WordPress, IndiaMART, the chat widget, your chatbots and automations, and anything you have built against this API. With it off, a broadcast to a list of any size goes out in full, at the rate you asked for. What this does NOT switch off: your billing state, your monthly spend budget, blocked contacts and opt-outs. Those are your money and your customers' consent, and nothing here moves them. **Meta's own limit does not go away.** Each number still has the daily limit Meta enforces, and Meta rejects everything past it. Those rejections count against the number's quality rating, which lowers the limit further and can end in Meta restricting the number. Guardian's cap existed to keep you the safe side of Meta's; with protection off, nothing does — so pace your own sending against `GET /api/v1/number-health`, which reports each number's real allowance either way. Guardian keeps measuring, scoring and alerting regardless. Requires the `number-health:write` scope. Body parameters: - `enabled` (boolean, required): true keeps every protection on (the default for every account); false turns all of them off Responses: 200 Saved — it applies to the next send, from any source; 400 `enabled` missing, or not true/false; 403 This API key does not have the number-health:write scope. Example: ```bash curl -X PUT "https://motherbot.io/api/v1/number-health/guard" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{"enabled": false}' ``` Response: ```json { "success": true, "data": { "enabled": false, "message": "Number protection is off. Nothing will hold a message back for your number's quality — your billing limits, spend budget, blocked contacts and opt-outs still apply." } } ``` ### Webhooks #### GET /api/v1/webhooks List webhook endpoints. Your registered endpoints with delivery stats, plus an `events` array of everything you may subscribe to. Secrets are never listed — see the create call. Example: ```bash curl "https://motherbot.io/api/v1/webhooks" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": [ { "id": "671aa...", "name": "Order sync", "url": "https://example.com/hooks/motherbot", "events": ["message.received"], "isActive": true, "stats": { "delivered": 8421, "failed": 3, "lastDeliveredAt": "2026-07-27T09:11:04Z" } } ], "events": ["message.received", "message.sent", "..."] } ``` #### POST /api/v1/webhooks Register a webhook endpoint. The other direction of the API — so you never have to poll for an inbound message. The URL must be publicly reachable: private, loopback and cloud-metadata addresses are rejected. The signing secret is returned ONCE by this response and never again; store it when you create the endpoint. Capped by your plan's webhook quota. Body parameters: - `url` (string, required): Publicly reachable https endpoint - `events` (string[], required): At least one. An unknown event is a 400 listing the valid ones - `name` (string, optional, default API webhook): Label shown in the dashboard - `secret` (string, optional): One is generated if you don't supply it - `isActive` (boolean, optional, default true): Create it paused by passing false — nothing is delivered until you enable it. Responses: 201 Registered; 400 Unknown event, or a URL we won't call; 402 Webhook limit reached on your plan. Example: ```bash curl -X POST "https://motherbot.io/api/v1/webhooks" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com/hooks/motherbot", "events": ["message.received", "message.failed"] }' ``` Response: ```json { "success": true, "data": { "id": "671aa...", "url": "https://example.com/hooks/motherbot", "events": ["message.received", "message.failed"], "secret": "whsec_9f2c…", "isActive": true }, "message": "Store the secret now — it is not returned again." } ``` #### PATCH /api/v1/webhooks/:id Update or pause an endpoint. Set `isActive: false` to pause deliveries during maintenance — the endpoint keeps its id and its stats, and you don't have to re-register it against your quota afterwards. Path parameters: - `id` (string, required): Webhook ID Body parameters: - `url` (string, optional): New endpoint URL - `events` (string[], optional): Replaces the subscription list - `name` (string, optional): Rename - `isActive` (boolean, optional): false pauses deliveries Example: ```bash curl -X PATCH "https://motherbot.io/api/v1/webhooks/671aa2..." \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "isActive": false }' ``` Response: ```json { "success": true, "data": { "id": "671aa...", "isActive": false } } ``` #### DELETE /api/v1/webhooks/:id Unregister an endpoint. Frees a slot against your plan's webhook quota. Path parameters: - `id` (string, required): Webhook ID Example: ```bash curl -X DELETE "https://motherbot.io/api/v1/webhooks/671aa2..." \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": { "id": "671aa2...", "deleted": true } } ``` ### Usage & Plan #### GET /api/v1/usage Plan limits, usage and feature flags. Call this before a long run. Every other endpoint can refuse with 402 (quota full) or 403 (feature not on the plan); without this one you can only discover those by hitting them — which means finding out mid-import that the contact quota ran out three hundred rows ago. `limit: -1` means unlimited, and `remaining` is null rather than a misleading number. Example: ```bash curl "https://motherbot.io/api/v1/usage" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": { "plan": { "name": "Growth", "subscriptionStatus": "active", "isActive": true }, "rateLimit": { "perMinute": 300 }, "limits": [ { "key": "contacts", "label": "Contacts", "used": 8412, "limit": 25000, "unlimited": false, "remaining": 16588, "percentUsed": 34 } ], "features": { "salesPipeline": true, "numberHealthGuardian": true, "webChat": false }, "integrations": ["shopify", "hubspot"] } } ``` ### Catalog Orders #### GET /api/v1/catalog-orders List captured WhatsApp cart checkouts. Carts customers submit through WhatsApp's native catalog/cart experience — captured automatically on every such message, independent of whether a chatbot flow is wired up for it. There is no create endpoint; subscribe to the `catalog_order.created` webhook to react the moment one lands instead of polling. Each cart carries `followUp`, the automatic reminder ladder: `status` is `scheduled` while more reminders are due and `stopped` once they've ended, with `stoppedReason` saying why in plain words (the customer replied, your team answered, the cart was dismissed, the 24-hour window closed). It is `null` when the organisation has cart follow-up switched off, which is a different answer from "reminders finished". Query parameters: - `contactId` (string, optional): Only this contact's carts - `status` (string, optional, allowed: new | pushed_to_store | dismissed): Filter by status - `page` (integer, optional, default 1): Page number - `limit` (integer, optional, default 20): Max 100 Example: ```bash curl "https://motherbot.io/api/v1/catalog-orders?status=new" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": [ { "id": "670c9f2...", "contactId": "664a1f8...", "totalValue": 1947, "currency": "INR", "status": "new", "items": [ { "productRetailerId": "sku-2201", "quantity": 2 } ], "followUp": { "status": "scheduled", "nextReminderAt": "2026-09-03T14:20:00.000Z", "remindersSent": 1, "stoppedReason": null, "stoppedAt": null, "attempts": [ { "step": 1, "sentAt": "2026-09-03T10:35:00.000Z", "status": "sent", "wamid": "wamid.HBgM...", "error": null } ] } } ], "pagination": { "page": 1, "limit": 20, "total": 6, "pages": 1 } } ``` #### GET /api/v1/catalog-orders/:id Get a captured cart. One cart, with the resolved product match (when the retailer id matched a local Product), the automatic reminder ladder's state in `followUp`, and — once pushed — the store's own order id. Path parameters: - `id` (string, required): Catalog order ID Example: ```bash curl "https://motherbot.io/api/v1/catalog-orders/670c9f2..." \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": { "id": "670c9f2...", "status": "new", "totalValue": 1947, "currency": "INR", "followUp": { "status": "stopped", "nextReminderAt": null, "remindersSent": 2, "stoppedReason": "The customer replied after sending their cart, so the reminders stopped.", "stoppedAt": "2026-09-03T12:04:00.000Z", "attempts": [ { "step": 1, "sentAt": "2026-09-03T10:35:00.000Z", "status": "sent", "wamid": "wamid.HBgM...", "error": null }, { "step": 2, "sentAt": "2026-09-03T11:50:00.000Z", "status": "sent", "wamid": "wamid.HBgN...", "error": null } ] } } } ``` #### PATCH /api/v1/catalog-orders/:id Dismiss a captured cart. The only write this endpoint allows — `status` must be `"dismissed"`. Pushing a cart into your connected store as a real order stays dashboard-only and staff-confirmed: a wrong retailer-id-to-variant mapping there would create a live, possibly mispriced order in your commerce backend, so that step deliberately has no API path. Dismissing also stops any automatic cart reminders still queued for it — the response comes back with `followUp.status` already `stopped`. Path parameters: - `id` (string, required): Catalog order ID Body parameters: - `status` (string, required, allowed: dismissed): The only accepted value Example: ```bash curl -X PATCH "https://motherbot.io/api/v1/catalog-orders/670c9f2..." \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "status": "dismissed" }' ``` Response: ```json { "success": true, "data": { "id": "670c9f2...", "status": "dismissed", "followUp": { "status": "stopped", "nextReminderAt": null, "remindersSent": 1, "stoppedReason": "The cart was dismissed, so the reminders stopped.", "stoppedAt": "2026-09-03T12:10:00.000Z", "attempts": [ { "step": 1, "sentAt": "2026-09-03T10:35:00.000Z", "status": "sent", "wamid": "wamid.HBgM...", "error": null } ] } } } ``` ### Recurring Broadcasts (needs the "recurringCampaigns" plan permission) #### GET /api/v1/recurring-campaigns List recurring/date-triggered broadcasts. A schedule ("every Friday 10am") or a per-contact date field (birthday, anniversary) that spawns and launches a real, ordinary Broadcast each time it fires. Query parameters: - `status` (string, optional, allowed: active | paused): Filter by status Example: ```bash curl "https://motherbot.io/api/v1/recurring-campaigns" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": [ { "_id": "670e1...", "name": "Weekly Digest", "status": "active", "trigger": { "type": "schedule", "frequency": "weekly", "dayOfWeek": 5, "time": "10:00", "timezone": "Asia/Kolkata" } } ] } ``` #### POST /api/v1/recurring-campaigns Create a recurring broadcast. Fires through the exact same launch path a one-off broadcast does — every plan limit, Number Health Guardian check and per-recipient tracking applies identically. `trigger` is either a `schedule` (frequency + optional dayOfWeek/dayOfMonth + time + timezone) or a `date_field` (a cf1–cf10 custom field + offsetDays + time + timezone). Body parameters: - `name` (string, required): Broadcast name - `whatsappAccountId` (string, required): Number to send from - `messageType` (string, optional, default template, allowed: template | freeform): - `templateId` (string, optional): Required unless messageType is freeform - `audienceType` (string, required, allowed: all | tags | segment): - `audienceTags` (string[], optional): Required when audienceType is tags - `segmentId` (string, optional): Required when audienceType is segment - `trigger` (object, required): Schedule or date-field trigger — see description - `rateLimitPerSecond` (number, optional, default 3): Responses: 201 Created; 402 Not on your plan, or a plan limit is full. Example: ```bash curl -X POST "https://motherbot.io/api/v1/recurring-campaigns" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "name": "Weekly Digest", "whatsappAccountId": "66aa1...", "templateId": "66f0a...", "audienceType": "all", "trigger": { "type": "schedule", "frequency": "weekly", "dayOfWeek": 5, "time": "10:00", "timezone": "Asia/Kolkata" } }' ``` Response: ```json { "success": true, "data": { "_id": "670e1...", "name": "Weekly Digest", "status": "active" } } ``` #### GET /api/v1/recurring-campaigns/:id Get a recurring broadcast. Includes totalRuns, totalRecipients and lastRunAt — the running tally across every occurrence it has fired. Path parameters: - `id` (string, required): Recurring broadcast ID Example: ```bash curl "https://motherbot.io/api/v1/recurring-campaigns/670e1..." \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": { "_id": "670e1...", "name": "Weekly Digest", "totalRuns": 12, "totalRecipients": 38400 } } ``` #### PATCH /api/v1/recurring-campaigns/:id Pause or resume. The only write this endpoint allows. Editing the audience, trigger or content is dashboard-only. Resuming a paused schedule recomputes its next run from now — it does not fire every occurrence it missed while paused. Path parameters: - `id` (string, required): Recurring broadcast ID Body parameters: - `status` (string, required, allowed: active | paused): Example: ```bash curl -X PATCH "https://motherbot.io/api/v1/recurring-campaigns/670e1..." \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "status": "paused" }' ``` Response: ```json { "success": true, "data": { "_id": "670e1...", "status": "paused" } } ``` #### DELETE /api/v1/recurring-campaigns/:id Delete a recurring broadcast. Stops future occurrences. Broadcasts it already spawned are untouched. Path parameters: - `id` (string, required): Recurring broadcast ID Example: ```bash curl -X DELETE "https://motherbot.io/api/v1/recurring-campaigns/670e1..." \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": { "id": "670e1...", "deleted": true } } ``` ### AI Knowledge Base (needs the "aiKnowledgeBase" plan permission) #### GET /api/v1/knowledge-base List knowledge bases. The collections your AI Reply chatbot node and inbox copilot retrieve from. Example: ```bash curl "https://motherbot.io/api/v1/knowledge-base" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": [ { "_id": "670c120...", "name": "Return Policy", "status": "ready", "documentCount": 4 } ] } ``` #### POST /api/v1/knowledge-base Create a knowledge base. Starts empty — add sources with POST /knowledge-base/:id/documents. Body parameters: - `name` (string, required): - `description` (string, optional): - `embeddingProvider` (string, optional, default local, allowed: local | openai | gemini): Fixed at creation — every document in this KB is embedded with it Responses: 201 Created; 402 Not on your plan, or the knowledge-base limit is full. Example: ```bash curl -X POST "https://motherbot.io/api/v1/knowledge-base" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "name": "Return Policy" }' ``` Response: ```json { "success": true, "data": { "_id": "670c120...", "name": "Return Policy", "status": "ready" } } ``` #### POST /api/v1/knowledge-base/:id/documents Add a URL or pasted text as a source. Runs synchronously — extracted, chunked and embedded before the response returns, so it only lands once the document is actually searchable (or has failed to become so). File upload is dashboard-only, since it needs multipart handling this endpoint doesn't take on. Also fires the `knowledge_base.document_processed` webhook, useful for an integration that doesn't want to hold the request open on a slow crawl. Path parameters: - `id` (string, required): Knowledge base ID Body parameters: - `sourceType` (string, required, allowed: url | text): - `url` (string, optional): Required when sourceType is url — crawled and stripped to text - `text` (string, optional): Required when sourceType is text - `title` (string, optional): Defaults to the page title (url) or first line (text) Responses: 201 Indexed; 400 ingest_failed — no usable text found, or the embedding provider has no API key configured. Example: ```bash curl -X POST "https://motherbot.io/api/v1/knowledge-base/670c120.../documents" \ -H "Authorization: Bearer motherbot_xxx" \ -H "Content-Type: application/json" \ -d '{ "sourceType": "url", "url": "https://mystore.com/pages/returns" }' ``` Response: ```json { "success": true, "data": { "documentId": "670c124...", "chunkCount": 14 } } ``` ### Calendly #### GET /api/v1/calendly/bookings List Calendly bookings. Read-only — there is no create endpoint, since Calendly has no "book on someone's behalf" API, only the invitee's own scheduling link. Subscribe to `calendly.booking_created` / `calendly.booking_canceled` to react the moment one changes instead of polling. Query parameters: - `contactId` (string, optional): Only this contact's bookings - `status` (string, optional, allowed: active | canceled | rescheduled): - `page` (integer, optional, default 1): Page number - `limit` (integer, optional, default 20): Max 100 Example: ```bash curl "https://motherbot.io/api/v1/calendly/bookings?status=active" \ -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": [ { "id": "670ca01...", "contactId": "664a1f8...", "eventTypeName": "30 Minute Demo", "startTime": "2026-08-05T09:30:00.000Z", "status": "active" } ], "pagination": { "page": 1, "limit": 20, "total": 3, "pages": 1 } } ``` ### Workflows #### GET /api/v1/workflows/catalogue List workflow triggers and steps. Every trigger and step a workflow can be built from. Call this BEFORE creating a workflow — a graph referring to a trigger or step that does not exist is rejected in full. The default response is a summary; pass `step` or `trigger` to get the complete field definitions for the entries you intend to use. Query parameters: - `step` (string, optional): Comma-separated step types to return in full, e.g. send_template,delay. Max 25. - `trigger` (string, optional): Comma-separated trigger keys to return in full. Max 25. Example: ```bash curl "https://motherbot.io/api/v1/workflows/catalogue" -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": { "categories": [ { "id": "messaging", "label": "Messaging", "color": "#16a34a", "blurb": "..." } ], "triggers": [ { "key": "contact.created", "kind": "event", "label": "Contact created", "description": "...", "category": "contacts" } ], "steps": [ { "type": "send_template", "label": "Send template", "category": "messaging", "blurb": "...", "branching": false } ], "limits": { "MAX_NODES": 100 } }, "hint": "Call again with ?step=type1,type2 or ?trigger=key1,key2 for the full field definitions of the entries you intend to use." } ``` #### GET /api/v1/workflows List workflows. Lists workflows newest-changed first. The graph (`nodes`, `edges`) is omitted — fetch a single workflow to get it. Archived workflows are hidden unless `status` asks for them. Query parameters: - `status` (string, optional, allowed: draft, active, paused, archived, all): Filter by status. Omitted hides archived workflows. - `page` (integer, optional, default 1): Page number - `limit` (integer, optional, default 20, allowed: 1-100): Results per page Example: ```bash curl "https://motherbot.io/api/v1/workflows?status=active" -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": [ { "_id": "68f1a...", "name": "Abandoned cart nudge", "status": "active", "trigger": { "type": "catalog.order.abandoned" }, "updatedAt": "2026-09-01T10:00:00.000Z" } ], "pagination": { "page": 1, "limit": 20, "total": 4, "pages": 1 } } ``` #### POST /api/v1/workflows Create a workflow. Creates a workflow. It is ALWAYS created as a draft, whatever you send — switch it on with a PATCH once you are happy with it. Any validation problems with the graph come back in `issues`; those marked blocking must be fixed before the workflow can be activated. Body parameters: - `name` (string, required): Workflow name. Must be unique within the organisation. - `description` (string, optional): Free-text note about what this workflow does - `folder` (string, optional): Folder name used to group workflows in the builder - `trigger` (object, optional): What starts the workflow: { type, config }. Defaults to a manual trigger. `type` must be a key from the workflow catalogue. - `nodes` (array, optional): The steps, as { id, type, position, config }. Each `type` must be a step from the workflow catalogue. - `edges` (array, optional): Connections between steps, as { id, source, target, sourceHandle } - `settings` (object, optional): Per-workflow settings such as run limits - `whatsappAccountId` (string, optional): WhatsApp number this workflow acts on Responses: 201 Created, as a draft; 400 Unknown trigger or step type, or too many steps; 402 Workflow limit reached on this plan; 409 A workflow with that name already exists. Example: ```bash curl -X POST "https://motherbot.io/api/v1/workflows" -H "Authorization: Bearer motherbot_xxx" -H "Content-Type: application/json" -d '{ "name": "Welcome new contacts", "trigger": { "type": "contact.created", "config": {} }, "nodes": [ { "id": "n1", "type": "delay", "position": { "x": 0, "y": 120 }, "config": { "duration": { "value": 10, "unit": "minutes" } } } ], "edges": [ { "id": "e1", "source": "trigger", "target": "n1" } ] }' ``` Response: ```json { "success": true, "data": { "_id": "68f1a...", "name": "Welcome new contacts", "status": "draft", "webhookId": "kR3f..." }, "issues": [] } ``` #### GET /api/v1/workflows/:id Get a workflow. Returns one workflow with its full graph, plus `issues` — the validation problems it has RIGHT NOW. A workflow can become invalid without being edited, when a plan changes or a step is withdrawn, so this is re-checked on every read. Path parameters: - `id` (string, required): Workflow id Example: ```bash curl "https://motherbot.io/api/v1/workflows/68f1a..." -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": { "_id": "68f1a...", "name": "Welcome new contacts", "status": "draft", "trigger": { "type": "contact.created" }, "nodes": [], "edges": [] }, "issues": [ { "level": "error", "nodeId": "n1", "message": "Pick a template to send." } ] } ``` #### PATCH /api/v1/workflows/:id Update or activate a workflow. Applies a partial update. Send `status: "active"` to switch the workflow on — that re-validates the whole graph first and is refused with 422 if anything blocking remains, so activation can never put a broken automation in front of a customer. Path parameters: - `id` (string, required): Workflow id Body parameters: - `name` (string, optional): New name - `description` (string, optional): New description - `folder` (string, optional): New folder - `trigger` (object, optional): Replacement trigger: { type, config } - `nodes` (array, optional): Replacement step list - `edges` (array, optional): Replacement connection list - `settings` (object, optional): Replacement settings - `whatsappAccountId` (string, optional): Move the workflow to another WhatsApp number. Send an empty string to unset it. - `status` (string, optional, allowed: draft, active, paused, archived): New status. `active` re-validates the graph and is refused if blocking issues remain. Responses: 200 Updated; 404 No workflow with that id; 422 Cannot activate — the graph still has blocking issues. Example: ```bash curl -X PATCH "https://motherbot.io/api/v1/workflows/68f1a..." -H "Authorization: Bearer motherbot_xxx" -H "Content-Type: application/json" -d '{ "status": "active" }' ``` Response: ```json { "success": true, "data": { "_id": "68f1a...", "status": "active" }, "issues": [] } ``` ### Chatbots #### GET /api/v1/chatbots/catalogue List chatbot node and trigger types. Every node type a chatbot flow can contain, every trigger type, and the channels this API key may build for. Call this BEFORE creating a chatbot — a flow referring to a node type that does not exist fails validation in full. Nodes carrying an `integration` need that integration connected; nodes carrying a `feature` need it on the plan. Example: ```bash curl "https://motherbot.io/api/v1/chatbots/catalogue" -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": { "channels": [ { "key": "whatsapp", "label": "WhatsApp" }, { "key": "telegram", "label": "Telegram" } ], "triggers": [ { "type": "keyword", "label": "Keyword", "description": "..." } ], "nodes": [ { "type": "message", "label": "Message / Ask", "color": "#16a34a", "desc": "..." } ] } } ``` #### GET /api/v1/chatbots List chatbots. Lists chatbots newest-changed first, without their flows. A key restricted to certain channels sees only bots on those channels. Query parameters: - `channel` (string, optional): Filter to one channel, e.g. whatsapp or telegram - `isActive` (boolean, optional): Filter to bots that are switched on (true) or off (false) - `page` (integer, optional, default 1): Page number - `limit` (integer, optional, default 20, allowed: 1-100): Results per page Example: ```bash curl "https://motherbot.io/api/v1/chatbots?isActive=true" -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": [ { "_id": "68f2b...", "name": "Order status bot", "channel": "whatsapp", "isActive": true, "trigger": { "type": "keyword", "keywords": ["order", "track"] } } ], "pagination": { "page": 1, "limit": 20, "total": 2, "pages": 1 } } ``` #### POST /api/v1/chatbots Create a chatbot. Creates a chatbot. It is ALWAYS created switched off — activate it with a PATCH once you are happy with the flow. The flow is deep-validated against your plan before it is saved: a node for an integration you have not connected is refused with 422 rather than saved and failed at run time. Body parameters: - `name` (string, required): Chatbot name - `description` (string, optional): Free-text note about what this bot does - `channel` (string, optional, default whatsapp): Channel this bot answers on. Must be one your API key is allowed to use. - `triggerType` (string, optional, default keyword, allowed: keyword, button_reply, ad_referral, first_message, any_message, opt_in, order): How the bot starts - `keywords` (string[], optional): Words that start the bot, when triggerType is keyword - `keywordMatchType` (string, optional, default contains, allowed: exact, contains, starts_with): How a keyword is matched against the inbound message - `buttonIds` (string[], optional): Button ids that start the bot, when triggerType is button_reply - `buttonMatchBy` (string, optional, default id, allowed: id, text): Whether a button trigger matches on the button's id or its visible text - `adSourceIds` (string[], optional): Click-to-WhatsApp ad ids that start the bot, when triggerType is ad_referral. WhatsApp only. Omit or send an empty array to answer EVERY ad and organic post. - `nodes` (array, optional): The flow's nodes, as { id, position, data: { nodeType, ... } }. Each `nodeType` must come from the chatbot catalogue. - `edges` (array, optional): Connections between nodes, as { id, source, target, sourceHandle } - `variables` (array, optional): Flow variables, as { name, type, defaultValue } - `whatsappAccountId` (string, optional): WhatsApp number this bot answers on. Defaults to the first one in scope. - `respectBusinessHours` (boolean, optional, default false): When true the bot only answers inside your configured business hours Responses: 201 Created, switched off; 402 Chatbot limit reached on this plan; 403 This API key may not use that channel; 409 Another live bot already claims that trigger; 422 The flow has blocking validation errors. Example: ```bash curl -X POST "https://motherbot.io/api/v1/chatbots" -H "Authorization: Bearer motherbot_xxx" -H "Content-Type: application/json" -d '{ "name": "Order status bot", "channel": "whatsapp", "triggerType": "keyword", "keywords": ["order", "track"], "nodes": [ { "id": "start", "type": "input", "position": { "x": 0, "y": 0 }, "data": { "label": "Start" } }, { "id": "n1", "position": { "x": 0, "y": 120 }, "data": { "nodeType": "message", "msgType": "text", "msgText": "What is your order number?", "waitForReply": true, "saveAs": "orderNo" } } ], "edges": [ { "id": "e1", "source": "start", "target": "n1" } ] }' ``` Response: ```json { "success": true, "data": { "_id": "68f2b...", "name": "Order status bot", "channel": "whatsapp", "isActive": false }, "warnings": [] } ``` #### GET /api/v1/chatbots/:id Get a chatbot. Returns one chatbot with its full flow. Path parameters: - `id` (string, required): Chatbot id Example: ```bash curl "https://motherbot.io/api/v1/chatbots/68f2b..." -H "Authorization: Bearer motherbot_xxx" ``` Response: ```json { "success": true, "data": { "_id": "68f2b...", "name": "Order status bot", "channel": "whatsapp", "isActive": false, "nodes": [], "edges": [] } } ``` #### PATCH /api/v1/chatbots/:id Update or activate a chatbot. Applies a partial update. Send `isActive: true` to switch the bot on — that re-validates the flow AND re-checks that no other live bot claims the same trigger, both of which can have changed since the bot was saved. Path parameters: - `id` (string, required): Chatbot id Body parameters: - `name` (string, optional): New name - `description` (string, optional): New description - `channel` (string, optional): Move the bot to another channel. Both the old and the new channel must be allowed by your key. - `triggerType` (string, optional, allowed: keyword, button_reply, ad_referral, first_message, any_message, opt_in, order): New trigger type - `keywords` (string[], optional): Replacement keyword list - `keywordMatchType` (string, optional, allowed: exact, contains, starts_with): New keyword match mode - `buttonIds` (string[], optional): Replacement button id list - `buttonMatchBy` (string, optional, allowed: id, text): New button match mode - `adSourceIds` (string[], optional): Replacement Click-to-WhatsApp ad id list for an ad_referral trigger. An empty array means every ad. - `nodes` (array, optional): Replacement node list - `edges` (array, optional): Replacement edge list - `variables` (array, optional): Replacement variable list - `respectBusinessHours` (boolean, optional): Whether the bot answers only inside business hours - `whatsappAccountId` (string, optional): Move the bot to another WhatsApp number. Send an empty string to unset it. - `isActive` (boolean, optional): Switch the bot on or off. Turning it on re-validates the flow and re-checks for trigger conflicts. Responses: 200 Updated; 404 No chatbot with that id; 409 Another live bot already claims that trigger; 422 Cannot activate — the flow has blocking errors. Example: ```bash curl -X PATCH "https://motherbot.io/api/v1/chatbots/68f2b..." -H "Authorization: Bearer motherbot_xxx" -H "Content-Type: application/json" -d '{ "isActive": true }' ``` Response: ```json { "success": true, "data": { "_id": "68f2b...", "isActive": true }, "warnings": [] } ``` ## Comparisons - [All comparisons](https://motherbot.io/compare) - [MotherBot vs respond.io](https://motherbot.io/compare/motherbot-vs-respond-io) - [MotherBot vs Wati](https://motherbot.io/compare/motherbot-vs-wati) - [MotherBot vs AiSensy](https://motherbot.io/compare/motherbot-vs-aisensy) - [MotherBot vs Interakt](https://motherbot.io/compare/motherbot-vs-interakt) - [MotherBot vs Gallabox](https://motherbot.io/compare/motherbot-vs-gallabox) - [MotherBot vs Picky Assist](https://motherbot.io/compare/motherbot-vs-pickyassist) - [MotherBot vs Zoko](https://motherbot.io/compare/motherbot-vs-zoko) - [MotherBot vs DoubleTick](https://motherbot.io/compare/motherbot-vs-doubletick) - [MotherBot vs Manychat](https://motherbot.io/compare/motherbot-vs-manychat) - [MotherBot vs Trengo](https://motherbot.io/compare/motherbot-vs-trengo) ## Optional - [Changelog](https://motherbot.io/docs/changelog): what changed, newest first. - [Blog](https://motherbot.io/blog): guides and articles. - [FAQs](https://motherbot.io/faqs) and [Help centre](https://motherbot.io/help) - [Status](https://motherbot.io/status) - [About](https://motherbot.io/about) and [Contact](https://motherbot.io/contact) - [Privacy Policy](https://motherbot.io/privacy), [Terms](https://motherbot.io/terms), [Data Processing Agreement](https://motherbot.io/dpa), [Refund Policy](https://motherbot.io/refund-policy)