Create EXTERNAL Conversation (API Key)
curl --request POST \
--url https://api.example.com/api/v1/conversations/external \
--header 'Content-Type: application/json' \
--data '
{
"external_id": "<string>",
"participants": [
{}
]
}
'import requests
url = "https://api.example.com/api/v1/conversations/external"
payload = {
"external_id": "<string>",
"participants": [{}]
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({external_id: '<string>', participants: [{}]})
};
fetch('https://api.example.com/api/v1/conversations/external', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/api/v1/conversations/external",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'external_id' => '<string>',
'participants' => [
[
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/api/v1/conversations/external"
payload := strings.NewReader("{\n \"external_id\": \"<string>\",\n \"participants\": [\n {}\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/api/v1/conversations/external")
.header("Content-Type", "application/json")
.body("{\n \"external_id\": \"<string>\",\n \"participants\": [\n {}\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/v1/conversations/external")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"external_id\": \"<string>\",\n \"participants\": [\n {}\n ]\n}"
response = http.request(request)
puts response.read_bodyConversations
Create EXTERNAL Conversation (API Key)
POST
/
api
/
v1
/
conversations
/
external
Create EXTERNAL Conversation (API Key)
curl --request POST \
--url https://api.example.com/api/v1/conversations/external \
--header 'Content-Type: application/json' \
--data '
{
"external_id": "<string>",
"participants": [
{}
]
}
'import requests
url = "https://api.example.com/api/v1/conversations/external"
payload = {
"external_id": "<string>",
"participants": [{}]
}
headers = {"Content-Type": "application/json"}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify({external_id: '<string>', participants: [{}]})
};
fetch('https://api.example.com/api/v1/conversations/external', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.example.com/api/v1/conversations/external",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'external_id' => '<string>',
'participants' => [
[
]
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.example.com/api/v1/conversations/external"
payload := strings.NewReader("{\n \"external_id\": \"<string>\",\n \"participants\": [\n {}\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.example.com/api/v1/conversations/external")
.header("Content-Type", "application/json")
.body("{\n \"external_id\": \"<string>\",\n \"participants\": [\n {}\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.example.com/api/v1/conversations/external")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Content-Type"] = 'application/json'
request.body = "{\n \"external_id\": \"<string>\",\n \"participants\": [\n {}\n ]\n}"
response = http.request(request)
puts response.read_bodyOverview
Create an EXTERNAL conversation using API keys only—no dashboard login. Use this from your backend (e.g. Node, Laravel, Django) when integrating Vocantly into your app. Same credentials you use for Issue SDK Token: X-Api-Key and X-Api-Secret.Backend-only. Store App ID, public key, and secret key on your server. Call this endpoint when a business event occurs (e.g. order placed, appointment booked). Then call Issue SDK Token for each participant and return
token + conversation_id to your frontend.When to Use This Endpoint
- You are building a backend that integrates Vocantly (SDK, external chat).
- You want to create conversations without using dashboard login (JWT).
- You already have an App and its public key + secret key from the dashboard.
Request Headers
| Header | Required | Description |
|---|---|---|
X-Api-Key | Yes | App public key (pk_…). Identifies the app—no appId in the URL or body. |
X-Api-Secret | Yes | App secret key (sk_…) |
Content-Type | Yes | application/json |
No appId in the request. The backend finds the app by
X-Api-Key (public key) and verifies X-Api-Secret. Use the same keys you use for Issue SDK Token (where appId is in the URL: POST /apps/:appId/tokens). For this endpoint, the app is implied by the headers.Request Body
string
required
Your app’s ID for this conversation (e.g. order ID, appointment ID, or sorted pair of user IDs). Must be unique per tenant. Idempotent: same
external_id returns the existing conversation.array
required
At least 2 participants. Each object:
external_user_id (required), name, email, role (optional). external_user_id must match the ID you pass when issuing SDK tokens for that user.Example Request
curl -X POST https://dev.vocantly.com/api/v1/conversations/external \
-H "Content-Type: application/json" \
-H "X-Api-Key: pk_xxxxx" \
-H "X-Api-Secret: sk_xxxxx" \
-d '{
"external_id": "order_789",
"participants": [
{ "external_user_id": "user_1", "name": "Alice", "email": "alice@example.com" },
{ "external_user_id": "user_2", "name": "Bob", "email": "bob@example.com" }
]
}'
Response
Same shape as Create Conversation:success, message, data with id, type, external_id, etc.
Success (201)
{
"success": true,
"message": "Conversation created successfully",
"data": {
"id": "770e8400-e29b-41d4-a716-446655440002",
"type": "external",
"external_id": "order_789",
"tenant_id": "...",
"created_at": "2024-01-01T00:00:00Z"
}
}
external_id already exists, the API returns that conversation (idempotent).
Error Responses
| Status | Description |
|---|---|
| 400 | Missing or invalid external_id or participants (e.g. fewer than 2) |
| 401 | Invalid or missing X-Api-Key / X-Api-Secret |
| 404 | No app found for this tenant (create an App in the dashboard first) |
Backend Integration Flow
- Create conversation (this endpoint) when your business event occurs (e.g. “Start chat” clicked, order placed).
- Issue SDK token for the current user: POST /apps/:appId/tokens with same API keys and
external_user_idmatching a participant. - Return
{ token, conversation_id: data.id }to your frontend. - Frontend uses SDK with
token, connects, joinsconversation_id, and sends/receives messages.
List EXTERNAL conversations
Inbox for external user
Get EXTERNAL messages
Message history
Issue SDK Token
Issue token for participants
SDK Installation
Use token in frontend
Conversations Guide
EXTERNAL conversations overview
Create Conversation (JWT)
Dashboard / other types