8 endpoints.
| Method | Path | Summary |
|---|---|---|
GET | /api/communities/{communityId}/okta-connect/channels | The community's connected channels |
DELETE | /api/communities/{communityId}/okta-connect/channels/{channelId} | Remove a channel from the community's workspace |
GET | /api/communities/{communityId}/okta-connect/embed/inbox | A signed iframe URL for the embedded Okta Connect inbox |
POST | /api/communities/{communityId}/okta-connect/provision | Ensure this community has an Okta Connect workspace |
POST | /api/communities/{communityId}/okta-connect/sso | Mint a one-time sign-in link into the Connect dashboard |
GET | /api/communities/{communityId}/okta-connect/status | Whether this community has an Okta Connect workspace |
POST | /api/communities/{communityId}/okta-connect/whatsapp/qr | Start a WhatsApp QR pairing session |
GET | /api/communities/{communityId}/okta-connect/whatsapp/qr/{sessionId} | Poll a WhatsApp QR pairing session |
GET /api/communities/{communityId}/okta-connect/channelsRead through the PARTNER API, so it needs no workspace token and keeps working before one has been minted. A community with no workspace answers an empty list rather than an error — "nothing connected yet" is a state, not a failure.
Auth: Bearer JWT required.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
communityId | path | yes | string (uuid) | — |
Responses
| Status | Description | Body |
|---|---|---|
200 | The channels, possibly empty | object |
403 | Not a member, missing okta_connect:access, FEATURE_NOT_AVAILABLE, or called with an API key (not allowed on this surface) | — |
502 | Okta Connect failed upstream (OKTA_CONNECT_WORKSPACE_GONE when the workspace was deleted there) | — |
DELETE /api/communities/{communityId}/okta-connect/channels/{channelId}Disconnects the channel (stopping any live gateway session) and deletes it upstream.
This exists because EVERY pairing attempt creates a channel, whether or not it ever produces a QR code. Without it, a few failed attempts leave a list of pending entries an admin cannot clear from inside Gurb. Okta Connect's own documentation names this endpoint for exactly that: "clean up stale channels — e.g. old WhatsApp links left 'awaiting scan'".
Uses the workspace-scoped token; the partner surface can list and reserve channels but cannot delete them.
Auth: Bearer JWT required.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
communityId | path | yes | string (uuid) | — |
channelId | path | yes | string | — |
Responses
| Status | Description | Body |
|---|---|---|
200 | Deleted | object |
403 | Not a member, missing okta_connect:access, FEATURE_NOT_AVAILABLE, or called with an API key (not allowed on this surface) | — |
409 | This community has no Okta Connect workspace yet | — |
502 | Okta Connect failed upstream (OKTA_CONNECT_WORKSPACE_GONE when the workspace was deleted there) | — |
GET /api/communities/{communityId}/okta-connect/embed/inboxReturns a URL to put in an <iframe src>. The URL carries an HS256 JWT signed with the embed shared secret, which is minted SERVER-SIDE and never sent to the browser as a secret — anyone holding it could mint an inbox session for any email address.
TWO UPSTREAM PRECONDITIONS, neither in this platform's control:
-
OKTA_CONNECT_EMBED_SECRETmust be set. The Partner API does not issue it; the operator hands it over out of band. Absent, this route answers 503 OKTA_CONNECT_EMBED_NOT_CONFIGURED. -
This platform's domain must be in Okta Connect's
frame-ancestorsallowlist. Measured 2026-08-19 that list was'self', getokta.io, dev.getokta.io, s.salla.sa and hamlah.on-forge.com. A correct token in an un-allowlisted frame renders a BLANK IFRAME with a console error and a 200 on the wire — a failure that looks like a bug here and is not one.
The response is Cache-Control: no-store: the URL is a bearer credential for its lifetime.
Auth: Bearer JWT required.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
communityId | path | yes | string (uuid) | — |
uiHide | query | no | enum: ai, close_conversation, assign_agent, sidebar, change_channel, snooze, sync_history, knowledge_base, smart_summary, sidebar_default_closed[] | Repeatable, or comma-joined. Strips Connect's own chrome so the frame reads as part of this platform. Unknown keys answer 400 and name the offender rather than failing at mint time. |
ttlSeconds | query | no | integer | Defaults to 3600 and is clamped to 14400. Kept short because the JWT rides in the query string and therefore lands in browser history and referrer logs; the client re-fetches rather than holding one longer. |
Responses
| Status | Description | Body |
|---|---|---|
200 | The iframe URL | object |
400 | An unknown uiHide key (the message names it) | — |
403 | Not a member, missing okta_connect:access, FEATURE_NOT_AVAILABLE, or called with an API key (not allowed on this surface) | — |
502 | Okta Connect failed upstream (OKTA_CONNECT_WORKSPACE_GONE when the workspace was deleted there) | — |
503 | The embed secret is not configured on this server | — |
POST /api/communities/{communityId}/okta-connect/provisionIdempotent. The workspace is keyed upstream on external_id = the Gurb community id, so a retry after a timeout returns the existing workspace rather than minting a duplicate tenant. The calling admin becomes the workspace owner upstream. Gurb has no community-owner concept to borrow, and this caller necessarily holds okta_connect:access, which only COMMUNITY_ADMIN is granted.
Auth: Bearer JWT required.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
communityId | path | yes | string (uuid) | — |
Responses
| Status | Description | Body |
|---|---|---|
200 | The workspace, whether it was just created or already existed | object |
403 | Not a member, missing okta_connect:access, FEATURE_NOT_AVAILABLE, or called with an API key (not allowed on this surface) | — |
429 | Rate limited — 10 burst, roughly 1 per 10 seconds | — |
502 | Okta Connect rejected the request or is unavailable | — |
503 | Not configured, or Okta Connect is rate limiting us | — |
POST /api/communities/{communityId}/okta-connect/ssoThe URL is single-use and expires in 300 seconds. It is RETURNED rather than redirected to, because a 302 would burn the ticket on any client that pre-fetches links. Provisions the workspace first if it does not exist yet.
Auth: Bearer JWT required.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
communityId | path | yes | string (uuid) | — |
Request body — application/json
| Field | Type | Required | Description |
|---|---|---|---|
redirect | string | no | Must start with /app/. Anything else — including an absolute URL or a protocol-relative //host — is replaced with /app, matching what Connect does upstream, so the caller is never told a landing page was honoured when it was discarded. |
Responses
| Status | Description | Body |
|---|---|---|
201 | The one-time URL | object |
403 | Not a member, missing okta_connect:access, FEATURE_NOT_AVAILABLE, or called with an API key (not allowed on this surface) | — |
409 | OKTA_CONNECT_OWNER_INACTIVE — the workspace has no owner installed upstream | — |
429 | Rate limited — 10 burst, roughly 1 per 10 seconds | — |
502 | Okta Connect failed upstream (OKTA_CONNECT_WORKSPACE_GONE when the workspace was deleted there) | — |
GET /api/communities/{communityId}/okta-connect/statusReads Gurb's own record only — no upstream call. Status must stay fast and must not fail when Okta Connect is down.
Auth: Bearer JWT required.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
communityId | path | yes | string (uuid) | — |
Responses
| Status | Description | Body |
|---|---|---|
200 | The stored workspace record, or provisioned=false | object |
403 | Missing okta_connect:access, or the community's plan does not include the okta_connect feature (body FEATURE_NOT_AVAILABLE). | — |
502 | Okta Connect failed upstream (OKTA_CONNECT_WORKSPACE_GONE when the workspace was deleted there) | — |
503 | This server has no Okta Connect partner credentials configured | — |
POST /api/communities/{communityId}/okta-connect/whatsapp/qrProvisions the workspace if needed, mints a workspace-scoped token if needed, then asks Okta Connect to create the channel and boot a pairing session. Poll the status route every few seconds until pending is false.
The workspace token never reaches the browser: this endpoint exists so that a credential able to read every conversation in the workspace stays on the server. The client only ever sees the QR string.
Auth: Bearer JWT required.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
communityId | path | yes | string (uuid) | — |
Request body — application/json
| Field | Type | Required | Description |
|---|---|---|---|
displayName | string | no | Channel label. Blank or missing falls back to "WhatsApp". |
Responses
| Status | Description | Body |
|---|---|---|
201 | The pairing session | object |
403 | Not a member, missing okta_connect:access, FEATURE_NOT_AVAILABLE, or called with an API key (not allowed on this surface) | — |
409 | OKTA_CONNECT_OWNER_INACTIVE (no owner installed upstream), or OKTA_CONNECT_CHANNEL_LIMIT_REACHED (one WhatsApp number per community) | — |
429 | Rate limited — pairing creates a channel upstream | — |
502 | Okta Connect rejected the request or returned no session id | — |
GET /api/communities/{communityId}/okta-connect/whatsapp/qr/{sessionId}Poll every ~3 seconds while pending is true. The QR payload rotates, so re-render it on every response. Stop as soon as pending is false — connected is success, and failed, qr_expired, disconnected and rate_limited are terminal too.
Auth: Bearer JWT required.
Parameters
| Name | In | Required | Type | Description |
|---|---|---|---|---|
communityId | path | yes | string (uuid) | — |
sessionId | path | yes | string | — |
Responses
| Status | Description | Body |
|---|---|---|
200 | The current state of the pairing session | object |
403 | Not a member, missing okta_connect:access, FEATURE_NOT_AVAILABLE, or called with an API key (not allowed on this surface) | — |
409 | This community has no Okta Connect workspace yet | — |
502 | Okta Connect failed upstream (OKTA_CONNECT_WORKSPACE_GONE when the workspace was deleted there) | — |