Conversations
Create, list, update, and manage conversations via the API
Conversations
Conversations are the core resource in Ndoto. Every customer interaction is a conversation.
Base path: /api/v1/accounts/:account_id/conversations
List conversations
Returns a paginated list of conversations in your account.
GET /api/v1/accounts/:account_id/conversationsQuery parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
page | number | No | Page number. Default: 1 |
sort | string | No | Sort field. Options: created_at, updated_at, last_activity_at |
status | string | No | Filter by status: open, resolved, pending, snoozed |
assignee_type | string | No | Filter: me, unassigned, all, assigned |
labels | string | No | Filter by label title |
Response
{
"data": {
"meta": {
"all_count": 120,
"mine_count": 30,
"unassigned_count": 15,
"assigned_count": 75
},
"payload": [
{
"id": 1,
"inbox_id": 2,
"status": "open",
"priority": "high",
"unread_count": 3,
"created_at": 1712000000,
"contact": {
"id": 10,
"name": "Jane Doe",
"email": "[email protected]"
},
"meta": {
"assignee": { "id": 5, "name": "Agent Name" },
"team": { "id": 1, "name": "Support" }
}
}
]
}
}const response = await fetch(
'https://app.usendoto.com/api/v1/accounts/1/conversations?status=open&page=1',
{
headers: {
'api_access_token': 'YOUR_TOKEN',
'Content-Type': 'application/json',
},
}
);
const data = await response.json();
console.log(data);import requests
response = requests.get(
'https://app.usendoto.com/api/v1/accounts/1/conversations',
headers={'api_access_token': 'YOUR_TOKEN'},
params={'status': 'open', 'page': 1},
)
print(response.json())<?php
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => 'https://app.usendoto.com/api/v1/accounts/1/conversations?status=open&page=1',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'api_access_token: YOUR_TOKEN',
'Content-Type: application/json',
],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);import 'package:http/http.dart' as http;
import 'dart:convert';
final response = await http.get(
Uri.parse('https://app.usendoto.com/api/v1/accounts/1/conversations?status=open&page=1'),
headers: {'api_access_token': 'YOUR_TOKEN'},
);
final data = jsonDecode(response.body);
print(data);require 'net/http'
require 'json'
uri = URI('https://app.usendoto.com/api/v1/accounts/1/conversations')
uri.query = URI.encode_www_form(status: 'open', page: 1)
req = Net::HTTP::Get.new(uri)
req['api_access_token'] = 'YOUR_TOKEN'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)Get a conversation
Returns a single conversation by its ID.
GET /api/v1/accounts/:account_id/conversations/:idPath parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
account_id | number | Yes | Your account ID |
id | number | Yes | Conversation ID |
const response = await fetch(
'https://app.usendoto.com/api/v1/accounts/1/conversations/42',
{
headers: { 'api_access_token': 'YOUR_TOKEN' },
}
);
const conversation = await response.json();
console.log(conversation);import requests
response = requests.get(
'https://app.usendoto.com/api/v1/accounts/1/conversations/42',
headers={'api_access_token': 'YOUR_TOKEN'},
)
print(response.json())<?php
$ch = curl_init('https://app.usendoto.com/api/v1/accounts/1/conversations/42');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['api_access_token: YOUR_TOKEN'],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);final response = await http.get(
Uri.parse('https://app.usendoto.com/api/v1/accounts/1/conversations/42'),
headers: {'api_access_token': 'YOUR_TOKEN'},
);
print(jsonDecode(response.body));uri = URI('https://app.usendoto.com/api/v1/accounts/1/conversations/42')
req = Net::HTTP::Get.new(uri)
req['api_access_token'] = 'YOUR_TOKEN'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)Create a conversation
Creates a new conversation.
POST /api/v1/accounts/:account_id/conversationsBody parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
inbox_id | number | Yes | The inbox to create the conversation in |
contact_id | number | Yes | The contact this conversation belongs to |
source_id | string | No | External identifier for the conversation |
assignee_id | number | No | Agent ID to assign the conversation to |
team_id | number | No | Team ID to assign the conversation to |
message | object | No | Initial message — { content: string } |
additional_attributes | object | No | Extra metadata to attach |
const response = await fetch(
'https://app.usendoto.com/api/v1/accounts/1/conversations',
{
method: 'POST',
headers: {
'api_access_token': 'YOUR_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({
inbox_id: 2,
contact_id: 10,
message: { content: 'Hello, how can I help you?' },
assignee_id: 5,
}),
}
);
const conversation = await response.json();
console.log(conversation);import requests
response = requests.post(
'https://app.usendoto.com/api/v1/accounts/1/conversations',
headers={'api_access_token': 'YOUR_TOKEN'},
json={
'inbox_id': 2,
'contact_id': 10,
'message': {'content': 'Hello, how can I help you?'},
'assignee_id': 5,
},
)
print(response.json())<?php
$payload = json_encode([
'inbox_id' => 2,
'contact_id' => 10,
'message' => ['content' => 'Hello, how can I help you?'],
'assignee_id' => 5,
]);
$ch = curl_init('https://app.usendoto.com/api/v1/accounts/1/conversations');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_HTTPHEADER => [
'api_access_token: YOUR_TOKEN',
'Content-Type: application/json',
],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);final response = await http.post(
Uri.parse('https://app.usendoto.com/api/v1/accounts/1/conversations'),
headers: {
'api_access_token': 'YOUR_TOKEN',
'Content-Type': 'application/json',
},
body: jsonEncode({
'inbox_id': 2,
'contact_id': 10,
'message': {'content': 'Hello, how can I help you?'},
'assignee_id': 5,
}),
);
print(jsonDecode(response.body));require 'net/http'
require 'json'
uri = URI('https://app.usendoto.com/api/v1/accounts/1/conversations')
req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
req['api_access_token'] = 'YOUR_TOKEN'
req.body = JSON.dump(
inbox_id: 2,
contact_id: 10,
message: { content: 'Hello, how can I help you?' },
assignee_id: 5
)
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)Update a conversation
Updates the priority or SLA policy of a conversation.
PATCH /api/v1/accounts/:account_id/conversations/:idBody parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
priority | string | No | urgent, high, medium, low |
sla_policy_id | number | No | ID of the SLA policy to apply |
const response = await fetch(
'https://app.usendoto.com/api/v1/accounts/1/conversations/42',
{
method: 'PATCH',
headers: {
'api_access_token': 'YOUR_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({ priority: 'urgent' }),
}
);
const updated = await response.json();
console.log(updated);response = requests.patch(
'https://app.usendoto.com/api/v1/accounts/1/conversations/42',
headers={'api_access_token': 'YOUR_TOKEN'},
json={'priority': 'urgent'},
)
print(response.json())<?php
$ch = curl_init('https://app.usendoto.com/api/v1/accounts/1/conversations/42');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'PATCH',
CURLOPT_POSTFIELDS => json_encode(['priority' => 'urgent']),
CURLOPT_HTTPHEADER => [
'api_access_token: YOUR_TOKEN',
'Content-Type: application/json',
],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);final response = await http.patch(
Uri.parse('https://app.usendoto.com/api/v1/accounts/1/conversations/42'),
headers: {
'api_access_token': 'YOUR_TOKEN',
'Content-Type': 'application/json',
},
body: jsonEncode({'priority': 'urgent'}),
);
print(jsonDecode(response.body));uri = URI('https://app.usendoto.com/api/v1/accounts/1/conversations/42')
req = Net::HTTP::Patch.new(uri, 'Content-Type' => 'application/json')
req['api_access_token'] = 'YOUR_TOKEN'
req.body = JSON.dump(priority: 'urgent')
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)Toggle conversation status
Changes the status of a conversation between open, resolved, pending, and snoozed.
POST /api/v1/accounts/:account_id/conversations/:id/toggle_statusBody parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
status | string | Yes | open, resolved, pending, or snoozed |
snoozed_until | timestamp | No | Unix timestamp — required when status is snoozed |
const response = await fetch(
'https://app.usendoto.com/api/v1/accounts/1/conversations/42/toggle_status',
{
method: 'POST',
headers: {
'api_access_token': 'YOUR_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({ status: 'resolved' }),
}
);
const result = await response.json();
console.log(result);response = requests.post(
'https://app.usendoto.com/api/v1/accounts/1/conversations/42/toggle_status',
headers={'api_access_token': 'YOUR_TOKEN'},
json={'status': 'resolved'},
)
print(response.json())<?php
$ch = curl_init('https://app.usendoto.com/api/v1/accounts/1/conversations/42/toggle_status');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode(['status' => 'resolved']),
CURLOPT_HTTPHEADER => [
'api_access_token: YOUR_TOKEN',
'Content-Type: application/json',
],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);final response = await http.post(
Uri.parse('https://app.usendoto.com/api/v1/accounts/1/conversations/42/toggle_status'),
headers: {
'api_access_token': 'YOUR_TOKEN',
'Content-Type': 'application/json',
},
body: jsonEncode({'status': 'resolved'}),
);
print(jsonDecode(response.body));uri = URI('https://app.usendoto.com/api/v1/accounts/1/conversations/42/toggle_status')
req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
req['api_access_token'] = 'YOUR_TOKEN'
req.body = JSON.dump(status: 'resolved')
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)Assign a conversation
Assigns an agent and/or team to a conversation.
POST /api/v1/accounts/:account_id/conversations/:id/assignmentsBody parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
assignee_id | number | No | Agent ID to assign |
team_id | number | No | Team ID to assign |
const response = await fetch(
'https://app.usendoto.com/api/v1/accounts/1/conversations/42/assignments',
{
method: 'POST',
headers: {
'api_access_token': 'YOUR_TOKEN',
'Content-Type': 'application/json',
},
body: JSON.stringify({ assignee_id: 5, team_id: 2 }),
}
);
const result = await response.json();
console.log(result);response = requests.post(
'https://app.usendoto.com/api/v1/accounts/1/conversations/42/assignments',
headers={'api_access_token': 'YOUR_TOKEN'},
json={'assignee_id': 5, 'team_id': 2},
)
print(response.json())<?php
$ch = curl_init('https://app.usendoto.com/api/v1/accounts/1/conversations/42/assignments');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => json_encode(['assignee_id' => 5, 'team_id' => 2]),
CURLOPT_HTTPHEADER => [
'api_access_token: YOUR_TOKEN',
'Content-Type: application/json',
],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);final response = await http.post(
Uri.parse('https://app.usendoto.com/api/v1/accounts/1/conversations/42/assignments'),
headers: {
'api_access_token': 'YOUR_TOKEN',
'Content-Type': 'application/json',
},
body: jsonEncode({'assignee_id': 5, 'team_id': 2}),
);
print(jsonDecode(response.body));uri = URI('https://app.usendoto.com/api/v1/accounts/1/conversations/42/assignments')
req = Net::HTTP::Post.new(uri, 'Content-Type' => 'application/json')
req['api_access_token'] = 'YOUR_TOKEN'
req.body = JSON.dump(assignee_id: 5, team_id: 2)
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)Search conversations
Search across conversations by content.
GET /api/v1/accounts/:account_id/conversations/searchQuery parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
q | string | Yes | Search query |
page | number | No | Page number |
const response = await fetch(
'https://app.usendoto.com/api/v1/accounts/1/conversations/search?q=billing+issue',
{
headers: { 'api_access_token': 'YOUR_TOKEN' },
}
);
const results = await response.json();
console.log(results);response = requests.get(
'https://app.usendoto.com/api/v1/accounts/1/conversations/search',
headers={'api_access_token': 'YOUR_TOKEN'},
params={'q': 'billing issue'},
)
print(response.json())<?php
$ch = curl_init('https://app.usendoto.com/api/v1/accounts/1/conversations/search?q=billing+issue');
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['api_access_token: YOUR_TOKEN'],
]);
$response = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($response);final uri = Uri.parse('https://app.usendoto.com/api/v1/accounts/1/conversations/search')
.replace(queryParameters: {'q': 'billing issue'});
final response = await http.get(
uri,
headers: {'api_access_token': 'YOUR_TOKEN'},
);
print(jsonDecode(response.body));uri = URI('https://app.usendoto.com/api/v1/accounts/1/conversations/search')
uri.query = URI.encode_www_form(q: 'billing issue')
req = Net::HTTP::Get.new(uri)
req['api_access_token'] = 'YOUR_TOKEN'
res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.parse(res.body)