Introduction
This documentation aims to provide all the information you need to work with our API.
<aside>As you scroll, you'll see code examples for working with the API in different programming languages in the dark area to the right (or as part of the content on mobile).
You can switch the language used with the tabs at the top right (or from the nav menu at the top left on mobile).</aside>
Authenticating requests
To authenticate requests, include an Authorization header with the value "Bearer {YOUR_API_TOKEN}".
All authenticated endpoints are marked with a requires authentication badge in the documentation below.
Issue a token from /app/integrations/api-tokens and pass it as Authorization: Bearer .... Tokens carry abilities (read / write / send / admin) — endpoints reject calls that lack the required ability.
Admin / Workspace channels
Reserve a channel slot
requires authentication
Creates a Channel row in disconnected state. Real provider
credentials (Cloud API access token, QR pairing session, etc.)
are wired up later via the dashboard or channel-specific
endpoint; this just lets the SDK list the channel ahead of time.
Example request:
curl --request POST \
"https://connect.getokta.io/api/v1/admin/workspaces/01HZK7P5R3Q6V0YH4XJ3M8WS001/channels" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"display_name\": \"Sales line\",
\"phone_number\": \"+966500000000\",
\"type\": \"architecto\"
}"
const url = new URL(
"https://connect.getokta.io/api/v1/admin/workspaces/01HZK7P5R3Q6V0YH4XJ3M8WS001/channels"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"display_name": "Sales line",
"phone_number": "+966500000000",
"type": "architecto"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Admin / Workspaces
Programmatic provisioning of Connect workspaces (Organizations) by a platform-admin token holder. Operates outside the per-tenant scope — the platform admin is the issuer of new tenants, not a member of any.
Create a workspace
requires authentication
Idempotent on slug: posting the same slug twice returns the
existing workspace with HTTP 200 instead of failing the unique
constraint, so installer modules can retry safely.
Example request:
curl --request POST \
"https://connect.getokta.io/api/v1/admin/workspaces" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Acme\",
\"slug\": \"acme\",
\"display_name\": \"Acme Corp.\",
\"locale\": \"en\",
\"metadata\": []
}"
const url = new URL(
"https://connect.getokta.io/api/v1/admin/workspaces"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Acme",
"slug": "acme",
"display_name": "Acme Corp.",
"locale": "en",
"metadata": []
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Update a workspace
requires authentication
Updates name, display_name, and metadata. The slug is
intentionally immutable once issued — modules and installer
tokens depend on a stable slug for routing.
Example request:
curl --request PATCH \
"https://connect.getokta.io/api/v1/admin/workspaces/01HZK7P5R3Q6V0YH4XJ3M8WS001" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"b\",
\"display_name\": \"n\"
}"
const url = new URL(
"https://connect.getokta.io/api/v1/admin/workspaces/01HZK7P5R3Q6V0YH4XJ3M8WS001"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "b",
"display_name": "n"
};
fetch(url, {
method: "PATCH",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Admin / Workspace tokens
Mint a Sanctum token for a workspace user
requires authentication
The plain-text token is returned exactly once. Persist it on the caller side immediately — Sanctum stores only a SHA-256 hash.
Example request:
curl --request POST \
"https://connect.getokta.io/api/v1/admin/workspaces/01HZK7P5R3Q6V0YH4XJ3M8WS001/tokens" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Connect installer token\",
\"abilities\": [
\"architecto\"
],
\"user_id\": \"architecto\",
\"expires_at\": \"2026-08-01T00:00:00Z\"
}"
const url = new URL(
"https://connect.getokta.io/api/v1/admin/workspaces/01HZK7P5R3Q6V0YH4XJ3M8WS001/tokens"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Connect installer token",
"abilities": [
"architecto"
],
"user_id": "architecto",
"expires_at": "2026-08-01T00:00:00Z"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Admin / Workspace users
Create a user in a workspace
requires authentication
Creates a new User and attaches them to the workspace as admin
(or the role you specify). If password_auto: true the action
generates a strong password and returns it ONCE in
data.one_time_password — Sanctum-style: not persisted in plain.
Example request:
curl --request POST \
"https://connect.getokta.io/api/v1/admin/workspaces/01HZK7P5R3Q6V0YH4XJ3M8WS001/users" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Sara Admin\",
\"email\": \"admin@acme.test\",
\"password\": \"|]|{+-\",
\"password_auto\": false,
\"role\": \"architecto\"
}"
const url = new URL(
"https://connect.getokta.io/api/v1/admin/workspaces/01HZK7P5R3Q6V0YH4XJ3M8WS001/users"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Sara Admin",
"email": "admin@acme.test",
"password": "|]|{+-",
"password_auto": false,
"role": "architecto"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Analytics
Read the organization's aggregated daily metrics (conversations, messages, agents and social insights) as totals per metric key.
Metrics summary
requires authentication
Returns totals per metric key over a date range (inclusive). Defaults
to the last 30 days when from/to are omitted. Pass platform to
scope to a single social platform.
Example request:
curl --request GET \
--get "https://connect.getokta.io/api/v1/analytics/metrics?from=2026-06-01&to=2026-06-30&platform=telegram" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"from\": \"2026-07-04T21:15:52\",
\"to\": \"2026-07-04T21:15:52\",
\"platform\": \"b\"
}"
const url = new URL(
"https://connect.getokta.io/api/v1/analytics/metrics"
);
const params = {
"from": "2026-06-01",
"to": "2026-06-30",
"platform": "telegram",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"from": "2026-07-04T21:15:52",
"to": "2026-07-04T21:15:52",
"platform": "b"
};
fetch(url, {
method: "GET",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"data": {
"from": "2026-06-01",
"to": "2026-06-30",
"platform": null,
"metrics": {
"messages.inbound": 1200,
"messages.outbound": 940,
"conversations.opened": 310,
"social.followers": 4820
}
}
}
Example response (422):
{
"message": "The from field must be a valid date.",
"errors": {
"from": [
"The from field must be a valid date."
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Campaigns
Broadcast (bulk / drip) message campaigns inside the authenticated organization. Create a draft, then queue it to materialize its audience.
List campaigns
requires authentication
Returns a paginated list of campaigns, newest first.
Example request:
curl --request GET \
--get "https://connect.getokta.io/api/v1/campaigns?status=draft&per_page=25&page=1" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://connect.getokta.io/api/v1/campaigns"
);
const params = {
"status": "draft",
"per_page": "25",
"page": "1",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": [
{
"id": "01HZK7P5R3Q6V0YH4XJ3M8CMP1",
"name": "Ramadan promo",
"type": "bulk",
"status": "draft",
"channel_id": "01HZK7P5R3Q6V0YH4XJ3M8CHN1",
"template_id": null,
"audience_size": 0,
"queued_count": 0,
"sent_count": 0,
"delivered_count": 0,
"read_count": 0,
"failed_count": 0,
"scheduled_at": null,
"started_at": null,
"finished_at": null,
"created_at": "2026-07-04T08:00:00+00:00"
}
],
"meta": {
"current_page": 1,
"per_page": 25,
"total": 1
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create a draft campaign
requires authentication
Creates a campaign in the draft state. The audience is not
materialized until you call the queue endpoint. audience_filter
accepts contact ULIDs and/or tag slugs; contact ULIDs are resolved to
the recipients selected at queue time.
Example request:
curl --request POST \
"https://connect.getokta.io/api/v1/campaigns" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"Ramadan promo\",
\"channel_id\": \"01HZK7P5R3Q6V0YH4XJ3M8CHN1\",
\"template_id\": \"01HZK7P5R3Q6V0YH4XJ3M8TPL1\",
\"type\": \"bulk\",
\"audience_filter\": {
\"contact_ids\": [
\"01HZK7P5R3Q6V0YH4XJ3M8AAA1\"
],
\"tag_slugs\": [
\"vip\"
]
}
}"
const url = new URL(
"https://connect.getokta.io/api/v1/campaigns"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "Ramadan promo",
"channel_id": "01HZK7P5R3Q6V0YH4XJ3M8CHN1",
"template_id": "01HZK7P5R3Q6V0YH4XJ3M8TPL1",
"type": "bulk",
"audience_filter": {
"contact_ids": [
"01HZK7P5R3Q6V0YH4XJ3M8AAA1"
],
"tag_slugs": [
"vip"
]
}
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"data": {
"id": "01HZK7P5R3Q6V0YH4XJ3M8CMP1",
"name": "Ramadan promo",
"type": "bulk",
"status": "draft",
"channel_id": "01HZK7P5R3Q6V0YH4XJ3M8CHN1",
"template_id": null,
"audience_size": 0,
"queued_count": 0,
"created_at": "2026-07-04T08:00:00+00:00"
}
}
Example response (404):
{
"message": "No query results for model [Channel]."
}
Example response (422):
{
"message": "The name field is required.",
"errors": {
"name": [
"The name field is required."
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Queue a campaign
requires authentication
Materializes the campaign's audience into recipients and moves it to
the running state. Only draft and scheduled campaigns can be
queued; other states are returned unchanged.
Example request:
curl --request POST \
"https://connect.getokta.io/api/v1/campaigns/01HZK7P5R3Q6V0YH4XJ3M8CMP1/queue" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://connect.getokta.io/api/v1/campaigns/01HZK7P5R3Q6V0YH4XJ3M8CMP1/queue"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Example response (200):
{
"data": {
"id": "01HZK7P5R3Q6V0YH4XJ3M8CMP1",
"name": "Ramadan promo",
"status": "running",
"audience_size": 120,
"queued_count": 120
}
}
Example response (404):
{
"message": "No query results for model [Campaign]."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Channels
Read-only listing of the WhatsApp channels connected to the active organization. Provisioning happens in the admin UI; the API only surfaces the connected channels so callers can pick one for outbound sends.
List channels
requires authentication
Example request:
curl --request GET \
--get "https://connect.getokta.io/api/v1/channels" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://connect.getokta.io/api/v1/channels"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": [
{
"id": "01HZK7P5R3Q6V0YH4XJ3M8CHN1",
"type": "cloud",
"status": "connected",
"display_name": "Sales line",
"phone_number": "+966500000000",
"connected_at": "2026-05-01T08:00:00+00:00",
"last_seen_at": "2026-05-06T10:21:00+00:00"
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Contacts
Manage WhatsApp contacts inside the authenticated organization.
List contacts
requires authentication
Returns a paginated list of contacts in the active organization, ordered by most recently created first.
Example request:
curl --request GET \
--get "https://connect.getokta.io/api/v1/contacts?search=ali&per_page=50&page=1" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://connect.getokta.io/api/v1/contacts"
);
const params = {
"search": "ali",
"per_page": "50",
"page": "1",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": [
{
"id": "01HZK7P5R3Q6V0YH4XJ3M8AAA1",
"wa_id": "966500000000",
"phone": "+966500000000",
"name": "Ali",
"email": null,
"language": "ar",
"last_seen_at": "2026-05-06T10:21:00+00:00",
"created_at": "2026-05-01T08:00:00+00:00"
}
],
"meta": {
"current_page": 1,
"per_page": 25,
"total": 1
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Create or update a contact
requires authentication
Idempotent on (organization, wa_id). Existing contact attributes are overwritten by the values you send — omit a field to leave it untouched.
Example request:
curl --request POST \
"https://connect.getokta.io/api/v1/contacts" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"wa_id\": \"966500000000\",
\"phone\": \"+966500000000\",
\"name\": \"Ali\",
\"email\": \"ali@example.com\",
\"language\": \"ar\",
\"profile\": [],
\"custom_fields\": []
}"
const url = new URL(
"https://connect.getokta.io/api/v1/contacts"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"wa_id": "966500000000",
"phone": "+966500000000",
"name": "Ali",
"email": "ali@example.com",
"language": "ar",
"profile": [],
"custom_fields": []
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"data": {
"id": "01HZK7P5R3Q6V0YH4XJ3M8AAA1",
"wa_id": "966500000000",
"phone": "+966500000000",
"name": "Ali",
"email": null,
"language": "ar"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Conversations
List conversations
requires authentication
Sorted by last_message_at descending so the freshest activity
appears first.
Example request:
curl --request GET \
--get "https://connect.getokta.io/api/v1/conversations?status=open&channel_id=01HZK7P5R3Q6V0YH4XJ3M8CHN1&per_page=25" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://connect.getokta.io/api/v1/conversations"
);
const params = {
"status": "open",
"channel_id": "01HZK7P5R3Q6V0YH4XJ3M8CHN1",
"per_page": "25",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": [
{
"id": "01HZK7P5R3Q6V0YH4XJ3M8CONV1",
"status": "open",
"priority": "normal",
"unread_count": 2,
"channel_id": "01HZK7P5R3Q6V0YH4XJ3M8CHN1",
"contact_id": "01HZK7P5R3Q6V0YH4XJ3M8AAA1",
"last_message_at": "2026-05-06T10:21:00+00:00"
}
]
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Embed widget
Server-side API for the embed SDK. The host app (e.g. a Laravel back-end) calls this to mint a short-lived signed token for the current visitor, then hands the token to the browser, which passes it to OktaWa.boot({ token }).
The token carries the visitor's external reference + optional context claims, so the embedded widget knows who it's talking to without ever exposing the org-side signing secret to the browser.
Mint a signed widget token
requires authentication
Example request:
curl --request POST \
"https://connect.getokta.io/api/v1/embed-tokens" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"slug\": \"marketing-site\",
\"subject\": \"user-12345\",
\"context\": [],
\"ttl_seconds\": 900
}"
const url = new URL(
"https://connect.getokta.io/api/v1/embed-tokens"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"slug": "marketing-site",
"subject": "user-12345",
"context": [],
"ttl_seconds": 900
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"data": {
"token": "eyJpc3MiOi...",
"expires_in": 900,
"slug": "marketing-site"
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Endpoints
POST api/v1/admin/organizations
requires authentication
Example request:
curl --request POST \
"https://connect.getokta.io/api/v1/admin/organizations" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"name\": \"b\",
\"owner_email\": \"zbailey@example.net\",
\"owner_password\": \"i\",
\"owner_name\": \"y\",
\"abilities\": [
\"write\"
]
}"
const url = new URL(
"https://connect.getokta.io/api/v1/admin/organizations"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"name": "b",
"owner_email": "zbailey@example.net",
"owner_password": "i",
"owner_name": "y",
"abilities": [
"write"
]
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
POST api/v1/admin/embed-secret/sync
requires authentication
Example request:
curl --request POST \
"https://connect.getokta.io/api/v1/admin/embed-secret/sync" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://connect.getokta.io/api/v1/admin/embed-secret/sync"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
POST api/v1/admin/embed-secret/provision
requires authentication
Example request:
curl --request POST \
"https://connect.getokta.io/api/v1/admin/embed-secret/provision" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"label\": \"b\",
\"issuer\": \"n\"
}"
const url = new URL(
"https://connect.getokta.io/api/v1/admin/embed-secret/provision"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"label": "b",
"issuer": "n"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
POST api/webhooks/telegram/{ulid}
requires authentication
Example request:
curl --request POST \
"https://connect.getokta.io/api/webhooks/telegram/architecto" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://connect.getokta.io/api/webhooks/telegram/architecto"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
POST api/webhooks/instagram
requires authentication
Example request:
curl --request POST \
"https://connect.getokta.io/api/webhooks/instagram" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://connect.getokta.io/api/webhooks/instagram"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
POST api/webhooks/twitter
requires authentication
Example request:
curl --request POST \
"https://connect.getokta.io/api/webhooks/twitter" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://connect.getokta.io/api/webhooks/twitter"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
POST api/integrations/meta/embedded-signup
requires authentication
Example request:
curl --request POST \
"https://connect.getokta.io/api/integrations/meta/embedded-signup" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"code\": \"b\",
\"waba_id\": \"n\"
}"
const url = new URL(
"https://connect.getokta.io/api/integrations/meta/embedded-signup"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"code": "b",
"waba_id": "n"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
POST api/integrations/qr/sessions
requires authentication
Example request:
curl --request POST \
"https://connect.getokta.io/api/integrations/qr/sessions" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"display_name\": \"b\"
}"
const url = new URL(
"https://connect.getokta.io/api/integrations/qr/sessions"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"display_name": "b"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
POST api/v1/admin/messages/transactional
requires authentication
Example request:
curl --request POST \
"https://connect.getokta.io/api/v1/admin/messages/transactional" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"to\": \"+3642559314\",
\"channel_id\": \"architecto\",
\"type\": \"template\",
\"text\": \"n\",
\"template\": {
\"name\": \"g\",
\"language\": \"zmiyvdljnikhwayk\",
\"components\": [
{
\"type\": \"architecto\"
}
]
}
}"
const url = new URL(
"https://connect.getokta.io/api/v1/admin/messages/transactional"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"to": "+3642559314",
"channel_id": "architecto",
"type": "template",
"text": "n",
"template": {
"name": "g",
"language": "zmiyvdljnikhwayk",
"components": [
{
"type": "architecto"
}
]
}
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
POST api/v1/admin/messages/otp
requires authentication
Example request:
curl --request POST \
"https://connect.getokta.io/api/v1/admin/messages/otp" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"to\": \"+3642559314\",
\"code\": \"56425\",
\"ttl_seconds\": 61,
\"purpose\": \"password_reset\",
\"locale\": \"en\"
}"
const url = new URL(
"https://connect.getokta.io/api/v1/admin/messages/otp"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"to": "+3642559314",
"code": "56425",
"ttl_seconds": 61,
"purpose": "password_reset",
"locale": "en"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
POST api/webhooks/neoleap
requires authentication
Example request:
curl --request POST \
"https://connect.getokta.io/api/webhooks/neoleap" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://connect.getokta.io/api/webhooks/neoleap"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Generate and store a new Embed SSO shared secret, returning the plain-text value so the caller can persist it on their side.
requires authentication
Rotating replaces the previous secret immediately; any outstanding tokens signed with the old secret will fail verification.
Example request:
curl --request POST \
"https://connect.getokta.io/api/v1/admin/embed-sso/provision" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://connect.getokta.io/api/v1/admin/embed-sso/provision"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
POST api/v1/admin/conversations/{ulid}/messages
requires authentication
Example request:
curl --request POST \
"https://connect.getokta.io/api/v1/admin/conversations/architecto/messages" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"type\": \"image\",
\"body\": \"b\",
\"caption\": \"n\",
\"media_url\": \"http:\\/\\/crooks.biz\\/et-fugiat-sunt-nihil-accusantium\",
\"template_name\": \"n\",
\"language\": \"ikhwaykcmyuwpwlv\"
}"
const url = new URL(
"https://connect.getokta.io/api/v1/admin/conversations/architecto/messages"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"type": "image",
"body": "b",
"caption": "n",
"media_url": "http:\/\/crooks.biz\/et-fugiat-sunt-nihil-accusantium",
"template_name": "n",
"language": "ikhwaykcmyuwpwlv"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
POST api/v1/admin/conversations/{ulid}/assign
requires authentication
Example request:
curl --request POST \
"https://connect.getokta.io/api/v1/admin/conversations/architecto/assign" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"user_ulid\": \"bngzmiyvdljnikhwaykcmyuwpw\"
}"
const url = new URL(
"https://connect.getokta.io/api/v1/admin/conversations/architecto/assign"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"user_ulid": "bngzmiyvdljnikhwaykcmyuwpw"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
POST api/v1/admin/conversations/{ulid}/read
requires authentication
Example request:
curl --request POST \
"https://connect.getokta.io/api/v1/admin/conversations/architecto/read" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://connect.getokta.io/api/v1/admin/conversations/architecto/read"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
POST api/v1/admin/contacts
requires authentication
Example request:
curl --request POST \
"https://connect.getokta.io/api/v1/admin/contacts" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"phone\": \"b\",
\"name\": \"n\"
}"
const url = new URL(
"https://connect.getokta.io/api/v1/admin/contacts"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"phone": "b",
"name": "n"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
POST api/v1/groups
requires authentication
Example request:
curl --request POST \
"https://connect.getokta.io/api/v1/groups" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"subject\": \"b\",
\"participants\": [
\"n\"
],
\"channel_id\": 16
}"
const url = new URL(
"https://connect.getokta.io/api/v1/groups"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"subject": "b",
"participants": [
"n"
],
"channel_id": 16
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
PATCH api/v1/groups/{ulid}
requires authentication
Example request:
curl --request PATCH \
"https://connect.getokta.io/api/v1/groups/architecto" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"subject\": \"b\",
\"description\": \"Et animi quos velit et fugiat.\"
}"
const url = new URL(
"https://connect.getokta.io/api/v1/groups/architecto"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"subject": "b",
"description": "Et animi quos velit et fugiat."
};
fetch(url, {
method: "PATCH",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
POST api/v1/groups/{ulid}/participants
requires authentication
Example request:
curl --request POST \
"https://connect.getokta.io/api/v1/groups/architecto/participants" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"participants\": [
\"b\"
]
}"
const url = new URL(
"https://connect.getokta.io/api/v1/groups/architecto/participants"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"participants": [
"b"
]
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
DELETE api/v1/groups/{ulid}/participants
requires authentication
Example request:
curl --request DELETE \
"https://connect.getokta.io/api/v1/groups/architecto/participants" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"participants\": [
\"b\"
]
}"
const url = new URL(
"https://connect.getokta.io/api/v1/groups/architecto/participants"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"participants": [
"b"
]
};
fetch(url, {
method: "DELETE",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
PUT api/v1/groups/{ulid}/picture
requires authentication
Example request:
curl --request PUT \
"https://connect.getokta.io/api/v1/groups/architecto/picture" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"picture_base64\": \"bngzmiyvdljnikhwaykcmyuwpwlvqwrsitcpscqldzsnrwtujwvlxjklqppwqbewtnnoqi\"
}"
const url = new URL(
"https://connect.getokta.io/api/v1/groups/architecto/picture"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"picture_base64": "bngzmiyvdljnikhwaykcmyuwpwlvqwrsitcpscqldzsnrwtujwvlxjklqppwqbewtnnoqi"
};
fetch(url, {
method: "PUT",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
POST api/v1/groups/{ulid}/sync
requires authentication
Example request:
curl --request POST \
"https://connect.getokta.io/api/v1/groups/architecto/sync" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://connect.getokta.io/api/v1/groups/architecto/sync"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "POST",
headers,
}).then(response => response.json());Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Messages
Public API surface for sending messages from external apps.
The integrating app provides a destination wa_id (or the ulid of an existing conversation) and the message body. We resolve / create the Contact + Conversation as needed, then hand off to SendMessageAction which queues the actual provider call.
Send a message
requires authentication
Send a free-form text or media message to a wa_id (auto-creates the
contact + conversation if needed) or into an existing conversation
via conversation_id. The message is queued; the response carries
the queued message resource — poll GET /conversations/{id}/messages
or subscribe to a webhook to track delivery status.
Example request:
curl --request POST \
"https://connect.getokta.io/api/v1/messages" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"channel_id\": \"01HZK7P5R3Q6V0YH4XJ3M8CHN1\",
\"conversation_id\": \"01HZK7P5R3Q6V0YH4XJ3M8CONV1\",
\"wa_id\": \"966500000000\",
\"type\": \"text\",
\"body\": \"Your order is on the way!\",
\"media_url\": \"https:\\/\\/cdn.example.com\\/file.pdf\"
}"
const url = new URL(
"https://connect.getokta.io/api/v1/messages"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"channel_id": "01HZK7P5R3Q6V0YH4XJ3M8CHN1",
"conversation_id": "01HZK7P5R3Q6V0YH4XJ3M8CONV1",
"wa_id": "966500000000",
"type": "text",
"body": "Your order is on the way!",
"media_url": "https:\/\/cdn.example.com\/file.pdf"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"data": {
"id": "01HZK7P5R3Q6V0YH4XJ3M8MSG1",
"conversation_id": "01HZK7P5R3Q6V0YH4XJ3M8CONV1",
"channel_id": "01HZK7P5R3Q6V0YH4XJ3M8CHN1",
"direction": "outbound",
"type": "text",
"body": "Your order is on the way!",
"status": "queued",
"created_at": "2026-05-06T10:21:00+00:00"
}
}
Example response (404):
{
"message": "Channel not found."
}
Example response (422):
{
"message": "The channel id field is required when conversation id is not present.",
"errors": {
"channel_id": [
"..."
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
OAuth
Exchanges a one-time authorization code from the Connect screen (/connect → user authorizes) for a Sanctum personal access token the external app can then use as Authorization: Bearer ...
The flow is intentionally simpler than full OAuth2: no client_secret, no PKCE. Security relies on:
- Codes are one-time (used_at flag).
- Codes expire in 5 minutes.
- Codes are bound to a redirect_uri at issue time and the host must send the same redirect_uri at exchange time, so an attacker who intercepts the redirect URL still can't redeem the code without also impersonating the registered redirect target.
Exchange code for token
requires authentication
Example request:
curl --request POST \
"https://connect.getokta.io/api/v1/oauth/token" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"code\": \"4f9e2c...\",
\"redirect_uri\": \"https:\\/\\/crm.example.com\\/oktawa\\/callback\"
}"
const url = new URL(
"https://connect.getokta.io/api/v1/oauth/token"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"code": "4f9e2c...",
"redirect_uri": "https:\/\/crm.example.com\/oktawa\/callback"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"data": {
"access_token": "1|abc...",
"token_type": "Bearer",
"abilities": [
"read",
"send"
]
}
}
Example response (400):
{
"error": "invalid_grant",
"message": "Authorization code is invalid, used, or expired."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Social posts
Compose a post and fan it out to one or more social channels (Telegram, X,
Instagram, …). A future scheduled_at schedules the post; otherwise it is
created as a draft.
List social posts
requires authentication
Returns a paginated list of social posts with their per-channel targets, newest first.
Schedule a social post
requires authentication
Composes a post and fans it out to the given channels. Every channel
must support feed/story publishing. With a future scheduled_at the
post is scheduled; without one it is created as a draft.
Tags
List the organization's tags and apply tags to a contact. Applying tags is idempotent — tag slugs that don't exist yet are created on the fly.
List tags
requires authentication
Returns a paginated list of tags, ordered by name.
Apply tags to a contact
requires authentication
Attaches the given tags to the contact, creating any that don't exist yet. Existing attachments are left untouched (idempotent). Returns the contact with its full tag list.
Templates
Send a template message
requires authentication
Send a Meta-approved template to a wa_id with optional positional variables (1-indexed in Meta, 0-indexed in the array — variable 1 = $variables[0]).
Example request:
curl --request POST \
"https://connect.getokta.io/api/v1/templates/send" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"channel_id\": \"01HZK7P5R3Q6V0YH4XJ3M8CHN1\",
\"wa_id\": \"966500000000\",
\"template_name\": \"order_ready\",
\"language\": \"ar\",
\"variables\": [
\"12345\",
\"120 SAR\"
]
}"
const url = new URL(
"https://connect.getokta.io/api/v1/templates/send"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"channel_id": "01HZK7P5R3Q6V0YH4XJ3M8CHN1",
"wa_id": "966500000000",
"template_name": "order_ready",
"language": "ar",
"variables": [
"12345",
"120 SAR"
]
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"data": {
"id": "01HZK7P5R3Q6V0YH4XJ3M8MSG2",
"type": "template",
"status": "queued"
}
}
Example response (404):
{
"message": "Template not found."
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Tickets
Support tickets inside the authenticated organization. Open a ticket in a pipeline, then transition it between stages.
List tickets
requires authentication
Returns a paginated list of tickets, newest first. Filter by the current stage category or by pipeline.
Example request:
curl --request GET \
--get "https://connect.getokta.io/api/v1/tickets?status=open&pipeline_id=01HZK7P5R3Q6V0YH4XJ3M8PIP1&per_page=25" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json"const url = new URL(
"https://connect.getokta.io/api/v1/tickets"
);
const params = {
"status": "open",
"pipeline_id": "01HZK7P5R3Q6V0YH4XJ3M8PIP1",
"per_page": "25",
};
Object.keys(params)
.forEach(key => url.searchParams.append(key, params[key]));
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
fetch(url, {
method: "GET",
headers,
}).then(response => response.json());Example response (200):
{
"data": [
{
"id": "01HZK7P5R3Q6V0YH4XJ3M8TKT1",
"number": 1001,
"subject": "Order not delivered",
"description": null,
"priority": "normal",
"status": "open",
"stage_id": "01HZK7P5R3Q6V0YH4XJ3M8STG1",
"stage": "New",
"pipeline_id": "01HZK7P5R3Q6V0YH4XJ3M8PIP1",
"contact_id": null,
"assigned_user_id": null,
"created_at": "2026-07-04T08:00:00+00:00"
}
],
"meta": {
"current_page": 1,
"per_page": 25,
"total": 1
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Open a ticket
requires authentication
Opens a ticket in the given pipeline (or the organization's default pipeline) at its first stage, applying the active SLA policy.
Example request:
curl --request POST \
"https://connect.getokta.io/api/v1/tickets" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"subject\": \"Order not delivered\",
\"description\": \"Customer says parcel never arrived.\",
\"pipeline_id\": \"01HZK7P5R3Q6V0YH4XJ3M8PIP1\",
\"contact_id\": \"01HZK7P5R3Q6V0YH4XJ3M8AAA1\",
\"priority\": \"high\"
}"
const url = new URL(
"https://connect.getokta.io/api/v1/tickets"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"subject": "Order not delivered",
"description": "Customer says parcel never arrived.",
"pipeline_id": "01HZK7P5R3Q6V0YH4XJ3M8PIP1",
"contact_id": "01HZK7P5R3Q6V0YH4XJ3M8AAA1",
"priority": "high"
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"data": {
"id": "01HZK7P5R3Q6V0YH4XJ3M8TKT1",
"number": 1001,
"subject": "Order not delivered",
"priority": "high",
"status": "open",
"stage_id": "01HZK7P5R3Q6V0YH4XJ3M8STG1",
"pipeline_id": "01HZK7P5R3Q6V0YH4XJ3M8PIP1"
}
}
Example response (404):
{
"message": "No query results for model [TicketPipeline]."
}
Example response (422):
{
"message": "No ticket pipeline is available.",
"errors": {
"pipeline_id": [
"No ticket pipeline is available."
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.
Transition a ticket to another stage
requires authentication
Moves the ticket to another stage within its own pipeline. Resolving to
a resolved/closed category stamps the corresponding timestamp.
Example request:
curl --request POST \
"https://connect.getokta.io/api/v1/tickets/01HZK7P5R3Q6V0YH4XJ3M8TKT1/transition" \
--header "Authorization: Bearer {YOUR_API_TOKEN}" \
--header "Content-Type: application/json" \
--header "Accept: application/json" \
--data "{
\"stage_id\": \"01HZK7P5R3Q6V0YH4XJ3M8STG2\",
\"note\": \"Escalated to logistics.\"
}"
const url = new URL(
"https://connect.getokta.io/api/v1/tickets/01HZK7P5R3Q6V0YH4XJ3M8TKT1/transition"
);
const headers = {
"Authorization": "Bearer {YOUR_API_TOKEN}",
"Content-Type": "application/json",
"Accept": "application/json",
};
let body = {
"stage_id": "01HZK7P5R3Q6V0YH4XJ3M8STG2",
"note": "Escalated to logistics."
};
fetch(url, {
method: "POST",
headers,
body: JSON.stringify(body),
}).then(response => response.json());Example response (200):
{
"data": {
"id": "01HZK7P5R3Q6V0YH4XJ3M8TKT1",
"status": "resolved",
"stage_id": "01HZK7P5R3Q6V0YH4XJ3M8STG2",
"resolved_at": "2026-07-04T09:00:00+00:00"
}
}
Example response (404):
{
"message": "No query results for model [TicketStage]."
}
Example response (422):
{
"message": "The stage id field is required.",
"errors": {
"stage_id": [
"The stage id field is required."
]
}
}
Received response:
Request failed with error:
Tip: Check that you're properly connected to the network.
If you're a maintainer of ths API, verify that your API is running and you've enabled CORS.
You can check the Dev Tools console for debugging information.