Channels
Where chat is exposed: the embeddable widget, its public configuration, and WhatsApp.
10 endpoints. 4 are reachable without a dashboard session — they are listed in the Integration API — and the other 6 require a Cognito JWT. The badge under each path says which.
/widget.js Embed widget bundle (301 to CDN when configured)
Auth Public — no credential
Path parameters
None.
Query parameters
None.Serves a fixed document and takes no input at all.
Body parameters
None.GET requests carry no body.
Response
Status codes
| Status | Meaning |
|---|---|
| 200 | Success. |
| 429 | Rate limited. See rate limits. |
curl
curl -X GET 'https://api.dev.oprag.ai/widget.js' \
-H 'X-Oprag-Key: sk_live_...' /v1/widget/{projectId}/config Public display configuration for a project's chat widget.
Auth Public — no credential
Before you call it
- Only served while the project is live or indexing and its widget is enabled.
- Returns
displayName,welcomeMessage, andtheme(primaryColor,position, and an optionalmode). theme.modeisauto,light, ordark.autofollows the visitor'sprefers-color-scheme.quickPromptsand the lead-capture fields appear only when those features are on, andescalationEnabledonly when the project has an escalation webhook or email.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
projectId | string | Required | Project the request applies to. Must belong to the calling workspace. |
Query parameters
None.Reads the resource named in the path; there is nothing else to select.
Body parameters
None.GET requests carry no body.
Response
Status codes
| Status | Meaning |
|---|---|
| 200 | Success. |
| 404 | No such resource in this workspace. |
| 429 | Rate limited. See rate limits. |
curl
curl -X GET 'https://api.dev.oprag.ai/v1/widget/{projectId}/config' \
-H 'X-Oprag-Key: sk_live_...' SDK equivalent `mountWidget()` reads this
/v1/webhooks/whatsapp Answers Meta's hub subscription challenge when the webhook is registered.
Auth Integration key
Before you call it
- Meta calls this when you register the webhook; your code never does.
hub.verify_tokenis compared against the globalWHATSAPP_VERIFY_TOKEN, never a per-project value.
Path parameters
None.
Query parameters
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
hub.mode | "subscribe" | Required | — | Meta sends subscribe. Any other value is rejected with 403. |
hub.verify_token | string | Required | — | Compared in constant time against the configured verify token. A mismatch is a 403. |
hub.challenge | string | Required | — | Echoed back verbatim as the plain-text 200 body when verification passes. |
Body parameters
None.GET requests carry no body.
Response
200 Success
1234567890 Status codes
| Status | Meaning |
|---|---|
| 200 | Verified. The body is hub.challenge verbatim, as plain text. |
| 401 | Missing, revoked, or wrong-environment key. |
| 403 | Invalid verification request when a parameter is missing or hub.mode is not subscribe; Verification token mismatch when the token does not match. |
| 429 | Rate limited. See rate limits. |
curl
curl -X GET 'https://api.dev.oprag.ai/v1/webhooks/whatsapp' \
-H 'X-Oprag-Key: sk_live_...' /v1/webhooks/whatsapp Receives inbound WhatsApp messages from Meta and answers them through the project's chat pipeline.
Auth Integration key
Before you call it
- Meta calls this, not your code. It needs an
X-Hub-Signature-256header —sha256=followed by an HMAC-SHA256 of the raw body under the app secret — and the raw JSON body. - Text messages only. Deliveries are de-duplicated on Meta's message id, and
phone_number_idselects which project answers. - Answers run through the shared chat pipeline with
channel: "whatsapp". - An unmapped or disabled connection is acknowledged without running chat at all, so Meta stops retrying.
Path parameters
None.
Query parameters
None.The provider signs and posts the whole payload; nothing is read from the URL.
Body parameters
Defined by the caller.Inbound message payload from WhatsApp.
Response
Status codes
| Status | Meaning |
|---|---|
| 200 | Acknowledged, as plain-text OK. Meta retries anything else, so this is the answer whenever the signature is valid. |
| 401 | Invalid webhook signature — the HMAC did not match. |
| 403 | Origin or IP not allowed for this project. |
| 429 | Rate limited. See rate limits. |
| 503 | WHATSAPP_APP_SECRET is not configured. |
curl
curl -X POST 'https://api.dev.oprag.ai/v1/webhooks/whatsapp' \
-H 'X-Oprag-Key: sk_live_...' /v1/projects/{projectId}/widget-config Widget settings (dashboard)
Auth Cognito JWT member
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
projectId | string | Required | Project the request applies to. Must belong to the calling workspace. |
Query parameters
None.Reads the resource named in the path; there is nothing else to select.
Body parameters
None.GET requests carry no body.
Response
Status codes
curl
curl -X GET 'https://api.dev.oprag.ai/v1/projects/{projectId}/widget-config' \
-H 'Authorization: Bearer <Cognito JWT>' /v1/projects/{projectId}/widget-config Update widget display name, welcome message, lead capture settings, optional leadFormFields (Growth+: max 5 on Growth, 10 on Pro/Enterprise), and theme (primaryColor, position, mode: auto | light | dark)
Auth Cognito JWT admin
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
projectId | string | Required | Project the request applies to. Must belong to the calling workspace. |
Query parameters
None.Everything it needs is in the request body.
Body parameters
| Name | Type | Required | Description |
|---|---|---|---|
enabled | boolean | Optional | Whether the feature is active. |
displayName | string | Optional | See the request example below. |
welcomeMessage | string | Optional | See the request example below. |
quickPrompts | string[] | Optional | Starter questions shown before the first message. |
leadCaptureEnabled | boolean | Optional | Offer the lead form when the documents cannot answer. |
leadCaptureTitle | string | Optional | Heading above the lead form. |
leadCaptureFields | "name" | "email"[] | Optional | Which built-in inputs to show. |
feedbackEnabled | boolean | Optional | Show thumbs up/down on answers. Defaults to on. |
leadFormFields | object[] | Optional | Additional custom fields. Growth and above. |
theme | object | Optional | Widget theme: primaryColor, position, mode. |
Response
Status codes
curl
curl -X PATCH 'https://api.dev.oprag.ai/v1/projects/{projectId}/widget-config' \
-H 'Authorization: Bearer <Cognito JWT>' /v1/projects/{projectId}/channels/whatsapp WhatsApp Business channel status for a project, with no secrets in it.
Auth Cognito JWT admin
Before you call it
statusisdisconnected,connected, orerror. Before the first connection,connectedandenabledare both false andstatusisdisconnected.- No secrets are returned — this is a
WhatsAppChannelStatus, in whichtokenConfiguredandwebhookVerifyConfiguredreport only whether they exist.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
projectId | string | Required | Project the request applies to. Must belong to the calling workspace. |
Query parameters
None.Reads the resource named in the path; there is nothing else to select.
Body parameters
None.GET requests carry no body.
Response
200 Success
{
"connected": true,
"enabled": true,
"phoneNumberId": "123456789",
"displayPhoneNumber": "+15551234567",
"wabaId": "987654321",
"tokenConfigured": true,
"webhookVerifyConfigured": true,
"lastInboundAt": "2026-08-11T12:00:00.000Z",
"status": "connected"
} Status codes
curl
curl -X GET 'https://api.dev.oprag.ai/v1/projects/{projectId}/channels/whatsapp' \
-H 'Authorization: Bearer <Cognito JWT>' /v1/projects/{projectId}/channels/whatsapp/connect Attach a WhatsApp Business phone number to the project.
Auth Cognito JWT admin
Before you call it
- Ownership of the number is verified against the Meta Graph API with the supplied token before anything is stored.
accessTokenis encrypted at rest, which requiresCHANNEL_TOKEN_ENCRYPTION_KEYto be configured.- Hub webhook verification always uses the global
WHATSAPP_VERIFY_TOKEN, never a per-project one. - A successful connect returns the project's
WhatsAppChannelStatus, exactly asGET …/channels/whatsappwould.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
projectId | string | Required | Project the request applies to. Must belong to the calling workspace. |
Query parameters
None.Everything it needs is in the request body.
Body parameters
| Name | Type | Required | Description |
|---|---|---|---|
phoneNumberId | string | Required | WhatsApp Business phone number id. |
wabaId | string | Required | WhatsApp Business account id. |
accessToken | string | Required | Long-lived access token. Encrypted at rest. |
displayPhoneNumber | string | Optional | Human-readable number to show in the dashboard. Defaults to the one Meta reports for phoneNumberId. |
Request
{
"phoneNumberId": "123456789",
"wabaId": "987654321",
"accessToken": "EAA...",
"displayPhoneNumber": "+15551234567"
} Response
200 Success
{
"connected": true,
"enabled": true,
"phoneNumberId": "123456789",
"displayPhoneNumber": "+15551234567",
"wabaId": "987654321",
"tokenConfigured": true,
"webhookVerifyConfigured": true,
"status": "connected"
} Status codes
| Status | Meaning |
|---|---|
| 200 | Success. |
| 400 | A required field is missing, or Meta's ownership check for the number failed. |
| 401 | Missing or expired JWT. |
| 403 | The signed-in user's role does not allow this. |
| 404 | No such resource in this workspace. |
| 409 | That phone number is already connected somewhere else. |
| 429 | Rate limited. See rate limits. |
| 503 | Channel token encryption is not configured. |
curl
curl -X POST 'https://api.dev.oprag.ai/v1/projects/{projectId}/channels/whatsapp/connect' \
-H 'Authorization: Bearer <Cognito JWT>' \
-H 'Content-Type: application/json' \
-d '{"phoneNumberId": "123456789","wabaId": "987654321","accessToken": "EAA...","displayPhoneNumber": "+15551234567"}' /v1/projects/{projectId}/channels/whatsapp Pause or resume an existing WhatsApp connection without deleting its credentials.
Auth Cognito JWT admin
Before you call it
- Returns the project's
WhatsAppChannelStatuswith the newenabledvalue.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
projectId | string | Required | Project the request applies to. Must belong to the calling workspace. |
Query parameters
None.Everything it needs is in the request body.
Body parameters
| Name | Type | Required | Description |
|---|---|---|---|
enabled | boolean | Optional | Pause or resume the channel without disconnecting it. |
Request
{ "enabled": false } Response
200 Success
{
"connected": true,
"enabled": false,
"phoneNumberId": "123456789",
"displayPhoneNumber": "+15551234567",
"wabaId": "987654321",
"tokenConfigured": true,
"webhookVerifyConfigured": true,
"status": "connected"
} Status codes
curl
curl -X PATCH 'https://api.dev.oprag.ai/v1/projects/{projectId}/channels/whatsapp' \
-H 'Authorization: Bearer <Cognito JWT>' \
-H 'Content-Type: application/json' \
-d '{ "enabled": false }' /v1/projects/{projectId}/channels/whatsapp Disconnect WhatsApp from the project.
Auth Cognito JWT admin
Before you call it
- Deletes both the connection row and the global
phone_number_idlookup.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
projectId | string | Required | Project the request applies to. Must belong to the calling workspace. |
Query parameters
None.Acts on the resource named in the path; there is nothing to choose.
Body parameters
None.DELETE requests carry no body.
Response
Status codes
curl
curl -X DELETE 'https://api.dev.oprag.ai/v1/projects/{projectId}/channels/whatsapp' \
-H 'Authorization: Bearer <Cognito JWT>' Ready to ship?
Get started free