Integrations
Connect your organization’s systems to the inbox, or build a custom connection using the API and signed outbound webhooks. Features depend on the connected account and the permissions enabled in your workspace.
Open Settings, Integrations to browse providers, review access requirements and manage your connections in one place. Owners and administrators manage organization connections. Every member manages their own calendar authorization.
Built-in connections
- Salesforce: customer records, accounts, opportunities and quotes.
- Xero: customer invoices, payment status and statement PDFs.
- Google Sheets: add leads to your organization’s spreadsheet.
- Google Calendar: connect your own account, select writable personal or shared calendars, create meetings and Google Meet links. WhatsApp messages and one-day or one-hour reminders require approved templates and enabled delivery.
- Hesabe: organization-scoped payment links and gateway status checks. Other payment providers are not currently available.
- JIDA: a custom organization integration for linked profiles, customer information and payment history. Review its bridge under Custom integrations.
Connections and access are scoped to the organization. Personal calendar connections remain tied to the user who connected them.
Commerce setup and availability
Foodics has a read-only merchant connector. Production activation and merchant verification are required before use. Direct Zyda and Ordable connections require provider API access and are not yet available. Shopify's existing Badala admin app is being prepared for distribution. Public installation is not available until its app identity, customer-data access and installation link are verified. Opening any setup page does not import customers or send messages.
Custom integration patterns
The examples below describe workflows you can build with the API and webhooks, plus channel automation settings.
1. CRM sync — push every new contact
Subscribe to contact.created and contact.updated. In your handler, upsert into your CRM by phone number. Use the contact's externalId field to round-trip the CRM's ID back into Badala — the bulk-import wizard then becomes a clean re-sync if you ever rebuild.
2. Order placement via WhatsApp
Subscribe to message.received. Parse the body for an order signal (e.g. ORDER 12345). POST to your ERP. Reply via the API:
POST /orgs/<orgId>/conversations/<convId>/messages
{ "type": "TEXT", "body": "Got it! Order #12345 is being prepared." }3. Slack notification on assignment
Subscribe to conversation.assigned. POST to a Slack incoming webhook with the contact's name and a deep link back to the inbox:
{
"text": ":speech_balloon: New conversation assigned to Yousef",
"attachments": [{
"title": "Open in Badala",
"title_link": "https://app.badala.app/inbox?conv=<convId>"
}]
}4. Migration from Gallabox / WATI
The contact import wizard at Contacts → Import accepts the standard Gallabox CSV/XLSX export shape — name, phone, email, tags, externalId, marketingConsent, company info, source, even original createdAt timestamps. The wizard auto-maps these fields.
Re-imports are idempotent: contacts are matched by externalId first, falling back to phone. Re-running the same export updates rather than duplicates.
5. Office hours auto-reply
Built into the channel settings — set per-day windows and an out-of-hours response. Fires on inbound messages outside the window, with a per-conversation cooldown to prevent repeating the same auto-reply on rapid-fire messages.
6. Auto-assignment
- Round-robin — distributes new conversations evenly across enabled members of the channel. Cursor is persisted, so the rotation survives restarts.
- By tag — first matching rule wins. Define rules like tag "sales" → assign to Aisha. Falls back to a configurable default.
7. Storing media outside Badala
WhatsApp media is downloaded from Meta and stored in S3 at s3://badala-ind/orgs/<orgId>/uploads/<key>, exposed through https://assets.badala.app via CloudFront. If you need a copy in your own bucket, subscribe to message.received and re-upload from the mediaUrl field.