Skip to content

WhatsApp Connector

Pair a WhatsApp channel and receive inbound messages. The partner flow is pairing under /connectors/whatsapp/*, not SQL-style providerConfigKey plus credentials. Phone OTP pairing is only available in the Fermi app.

Base URL

BASE_URL = "https://api.fermi.dev/public/v1"

Authentication

Authorization: Bearer <service-actor-token>

Required Scopes: connectors:read, connectors:write, connectors:sync

Start pairing

POST /connectors/whatsapp/pairing-session

{
  "reconnectConnectionId": null
}

Response: { "pairingSessionId", "qrBase64" } or { "alreadyConnected": true, "connectionId" }.

Poll pairing

GET /connectors/whatsapp/pairing-status?pairingSessionId={id}

Response: { "status": "pending" | "connected" | "duplicate" | "failed", "qrBase64?", "phoneNumber?", "error?" }

Groups and health

GET /connectors/whatsapp/groups?pairingSessionId={id}

GET /connectors/whatsapp/connection-health?connectionId={id}{ connectionId, connected, stopped, phoneNumber }

Finalize

POST /connectors/whatsapp/finalize

{
  "pairingSessionId": "SESSION_ID",
  "connectionName": "Support WhatsApp",
  "selectedGroups": [],
  "syncMode": "all",
  "description": "Support inbox"
}

Response: { "success": true, "connectionId": "..." }

Abandon

POST /connectors/whatsapp/abandon

{
  "pairingSessionId": "SESSION_ID"
}

Inbound webhook (callback)

WhatsApp posts to:

POST /webhooks/whatsapp/{connectionId}?s={secret}

Partners configure this URL in the channel provider. Do not call it as a substitute for pairing.

Sync flush

POST /sync/enqueue

{
  "connectionId": "CONNECTION_ID",
  "providerKey": "whatsapp",
  "whatsappFlush": true
}

Summary

Method Path
POST /connectors/whatsapp/pairing-session
GET /connectors/whatsapp/pairing-status
GET /connectors/whatsapp/groups
POST /connectors/whatsapp/finalize
POST /connectors/whatsapp/abandon
GET /connectors/whatsapp/connection-health
POST /webhooks/whatsapp/{connectionId}
POST /sync/enqueue

Next Steps