Worked request and response samples
Copy a request body as written, substitute your own ids, and compare the response envelope. Successful writes return{ data, meta }; failures return Devotel Orbit’s { error, meta } envelope, shown once below under Error envelope.
List agents
GET /api/v1/agents/status=active to hide drafts, or search to match on name. The meta.pagination.cursor value on the response feeds the next page’s cursor query parameter.
Request
cURL
curl -X GET "https://api.orbit.devotel.io/api/v1/agents/" \
-H "X-API-Key: dv_live_sk_your_key_here"
Node.js
import { Orbit } from '@devotel-orbit/node'
const orbit = new Orbit({
apiKey: process.env.ORBIT_API_KEY!,
})
const res = await fetch('https://api.orbit.devotel.io/api/v1/agents/', {
method: 'GET',
headers: {
'X-API-Key': process.env.ORBIT_API_KEY!,
},
})
console.log(await res.json())
Python
import os, requests
headers = {"X-API-Key": os.environ["ORBIT_API_KEY"]}
r = requests.get("https://api.orbit.devotel.io/api/v1/agents/", headers=headers)
print(r.json())
Go
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.orbit.devotel.io/api/v1/agents/", nil)
req.Header.Set("X-API-Key", os.Getenv("ORBIT_API_KEY"))
http.DefaultClient.Do(req)
}
Ruby
require 'net/http'
require 'json'
uri = URI('https://api.orbit.devotel.io/api/v1/agents/')
req = Net::HTTP::Get.new(uri)
req['X-API-Key'] = ENV['ORBIT_API_KEY']
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
puts res.body
PHP
<?php
$ch = curl_init('https://api.orbit.devotel.io/api/v1/agents/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'X-API-Key: ' . getenv('ORBIT_API_KEY'),
]);
echo curl_exec($ch);
{
"data": [
{
"id": "agt_3f6a81c2d4e5471a9b0c2d5e",
"name": "After-hours support",
"status": "active",
"type": "chatbot",
"model": "claude-sonnet-4-6",
"active_conversations": 3,
"conversation_count": 137,
"total_tokens": 84129,
"last_active_at": "2026-08-01T12:00:00.000Z",
"created_at": "2026-07-20T09:30:00.000Z",
"updated_at": "2026-08-01T11:45:00.000Z"
}
],
"meta": {
"request_id": "req_agt_list",
"timestamp": "2026-08-01T12:00:00.000Z",
"pagination": {
"cursor": "2026-07-20T09:30:00.000Z|agt_3f6a81c2d4e5471a9b0c2d5e",
"has_more": true,
"total": 24
}
}
}
Get one agent
GET /api/v1/agents/{id}temperature, max_tokens), tools, and the bound knowledge_base_ids. The sample id below is the same one this page uses in every call.
Request
cURL
curl -X GET "https://api.orbit.devotel.io/api/v1/agents/{id}" \
-H "X-API-Key: dv_live_sk_your_key_here"
Node.js
import { Orbit } from '@devotel-orbit/node'
const orbit = new Orbit({
apiKey: process.env.ORBIT_API_KEY!,
})
const res = await fetch('https://api.orbit.devotel.io/api/v1/agents/{id}', {
method: 'GET',
headers: {
'X-API-Key': process.env.ORBIT_API_KEY!,
},
})
console.log(await res.json())
Python
import os, requests
headers = {"X-API-Key": os.environ["ORBIT_API_KEY"]}
r = requests.get("https://api.orbit.devotel.io/api/v1/agents/{id}", headers=headers)
print(r.json())
Go
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.orbit.devotel.io/api/v1/agents/{id}", nil)
req.Header.Set("X-API-Key", os.Getenv("ORBIT_API_KEY"))
http.DefaultClient.Do(req)
}
Ruby
require 'net/http'
require 'json'
uri = URI('https://api.orbit.devotel.io/api/v1/agents/{id}')
req = Net::HTTP::Get.new(uri)
req['X-API-Key'] = ENV['ORBIT_API_KEY']
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
puts res.body
PHP
<?php
$ch = curl_init('https://api.orbit.devotel.io/api/v1/agents/{id}');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'X-API-Key: ' . getenv('ORBIT_API_KEY'),
]);
echo curl_exec($ch);
{
"data": {
"id": "agt_7e3b9c1f",
"name": "After-hours support",
"status": "active",
"type": "chatbot",
"model": "claude-sonnet-4-6",
"system_prompt": "Answer from the knowledge base; escalate billing questions.",
"temperature": 0.3,
"max_tokens": 1024,
"knowledge_base_ids": ["kb_7c1f2a9d4b8e4f1a9c3d5e7b0a2c4e6f"]
},
"meta": {
"request_id": "req_agt_get",
"timestamp": "2026-08-01T12:00:00.000Z"
}
}
Create an agent
POST /api/v1/agents/name is required. Everything else — type, model, system_prompt, generation settings, tools, knowledge_base_ids — falls back to tenant defaults. Bind the agent to one or more knowledge bases with knowledge_base_ids and it grounds its answers on that content; every id is checked against your workspace at create time.
Request
cURL
curl -X POST "https://api.orbit.devotel.io/api/v1/agents/" \
-H "X-API-Key: dv_live_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"name": "After-hours support",
"type": "chatbot",
"model": "claude-sonnet-4-6",
"system_prompt": "Answer from the knowledge base; escalate billing questions.",
"knowledge_base_ids": [
"kb_7c1f2a9d4b8e4f1a9c3d5e7b0a2c4e6f"
]
}'
Node.js
import { Orbit } from '@devotel-orbit/node'
const orbit = new Orbit({
apiKey: process.env.ORBIT_API_KEY!,
})
const res = await fetch('https://api.orbit.devotel.io/api/v1/agents/', {
method: 'POST',
headers: {
'X-API-Key': process.env.ORBIT_API_KEY!,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "After-hours support",
"type": "chatbot",
"model": "claude-sonnet-4-6",
"system_prompt": "Answer from the knowledge base; escalate billing questions.",
"knowledge_base_ids": [
"kb_7c1f2a9d4b8e4f1a9c3d5e7b0a2c4e6f"
]
}),
})
console.log(await res.json())
Python
import os, requests
headers = {"X-API-Key": os.environ["ORBIT_API_KEY"]}
headers["Content-Type"] = "application/json"
r = requests.post("https://api.orbit.devotel.io/api/v1/agents/", headers=headers, json={
"name": "After-hours support",
"type": "chatbot",
"model": "claude-sonnet-4-6",
"system_prompt": "Answer from the knowledge base; escalate billing questions.",
"knowledge_base_ids": [
"kb_7c1f2a9d4b8e4f1a9c3d5e7b0a2c4e6f"
]
})
print(r.json())
Go
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("POST", "https://api.orbit.devotel.io/api/v1/agents/", bytes.NewBuffer([]byte(`{
"name": "After-hours support",
"type": "chatbot",
"model": "claude-sonnet-4-6",
"system_prompt": "Answer from the knowledge base; escalate billing questions.",
"knowledge_base_ids": [
"kb_7c1f2a9d4b8e4f1a9c3d5e7b0a2c4e6f"
]
}`)))
req.Header.Set("X-API-Key", os.Getenv("ORBIT_API_KEY"))
req.Header.Set("Content-Type", "application/json")
http.DefaultClient.Do(req)
}
Ruby
require 'net/http'
require 'json'
uri = URI('https://api.orbit.devotel.io/api/v1/agents/')
req = Net::HTTP::Post.new(uri)
req['X-API-Key'] = ENV['ORBIT_API_KEY']
req['Content-Type'] = 'application/json'
req.body = {
"name": "After-hours support",
"type": "chatbot",
"model": "claude-sonnet-4-6",
"system_prompt": "Answer from the knowledge base; escalate billing questions.",
"knowledge_base_ids": [
"kb_7c1f2a9d4b8e4f1a9c3d5e7b0a2c4e6f"
]
}.to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
puts res.body
PHP
<?php
$ch = curl_init('https://api.orbit.devotel.io/api/v1/agents/');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'X-API-Key: ' . getenv('ORBIT_API_KEY'),
'Content-Type: application/json',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, <<<JSON
{
"name": "After-hours support",
"type": "chatbot",
"model": "claude-sonnet-4-6",
"system_prompt": "Answer from the knowledge base; escalate billing questions.",
"knowledge_base_ids": [
"kb_7c1f2a9d4b8e4f1a9c3d5e7b0a2c4e6f"
]
}
JSON);
echo curl_exec($ch);
{
"data": {
"id": "agt_3f6a81c2d4e5471a9b0c2d5e81c2d4a5",
"name": "After-hours support",
"type": "chatbot",
"status": "draft",
"model": "claude-sonnet-4-6",
"knowledge_base_ids": ["kb_7c1f2a9d4b8e4f1a9c3d5e7b0a2c4e6f"]
},
"meta": {
"request_id": "req_agt_create",
"timestamp": "2026-08-01T12:00:00.000Z"
}
}
Deploy the agent
POST /api/v1/agents/{id}/deploydraft onto one channel. channel is required — one of webhook, sms, whatsapp, voice, rcs. webhook_url is required when channel is webhook; phone_number is required for SMS / WhatsApp / voice deployments. Deploying flips status to active; there is also a matching POST /api/v1/agents/{id}/undeploy.
Request
cURL
curl -X POST "https://api.orbit.devotel.io/api/v1/agents/{id}/deploy" \
-H "X-API-Key: dv_live_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"channel": "webhook",
"webhook_url": "https://hooks.yourapp.example/agents/support"
}'
Node.js
import { Orbit } from '@devotel-orbit/node'
const orbit = new Orbit({
apiKey: process.env.ORBIT_API_KEY!,
})
const res = await fetch('https://api.orbit.devotel.io/api/v1/agents/{id}/deploy', {
method: 'POST',
headers: {
'X-API-Key': process.env.ORBIT_API_KEY!,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"channel": "webhook",
"webhook_url": "https://hooks.yourapp.example/agents/support"
}),
})
console.log(await res.json())
Python
import os, requests
headers = {"X-API-Key": os.environ["ORBIT_API_KEY"]}
headers["Content-Type"] = "application/json"
r = requests.post("https://api.orbit.devotel.io/api/v1/agents/{id}/deploy", headers=headers, json={
"channel": "webhook",
"webhook_url": "https://hooks.yourapp.example/agents/support"
})
print(r.json())
Go
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("POST", "https://api.orbit.devotel.io/api/v1/agents/{id}/deploy", bytes.NewBuffer([]byte(`{
"channel": "webhook",
"webhook_url": "https://hooks.yourapp.example/agents/support"
}`)))
req.Header.Set("X-API-Key", os.Getenv("ORBIT_API_KEY"))
req.Header.Set("Content-Type", "application/json")
http.DefaultClient.Do(req)
}
Ruby
require 'net/http'
require 'json'
uri = URI('https://api.orbit.devotel.io/api/v1/agents/{id}/deploy')
req = Net::HTTP::Post.new(uri)
req['X-API-Key'] = ENV['ORBIT_API_KEY']
req['Content-Type'] = 'application/json'
req.body = {
"channel": "webhook",
"webhook_url": "https://hooks.yourapp.example/agents/support"
}.to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
puts res.body
PHP
<?php
$ch = curl_init('https://api.orbit.devotel.io/api/v1/agents/{id}/deploy');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'X-API-Key: ' . getenv('ORBIT_API_KEY'),
'Content-Type: application/json',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, <<<JSON
{
"channel": "webhook",
"webhook_url": "https://hooks.yourapp.example/agents/support"
}
JSON);
echo curl_exec($ch);
{
"data": {
"id": "agt_3f6a81c2d4e5471a9b0c2d5e81c2d4a5",
"status": "active",
"channel": "webhook"
},
"meta": {
"request_id": "req_agt_deploy",
"timestamp": "2026-08-01T12:00:00.000Z"
}
}
Define an eval dataset
POST /api/v1/agents/{agentId}/evals/datasetsname plus at least one rows entry are required; each row carries an input (the user turn) and expected_output (the answer you grade). row_count updates as rows come and go.
Request
cURL
curl -X POST "https://api.orbit.devotel.io/api/v1/agents/{agentId}/evals/datasets" \
-H "X-API-Key: dv_live_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"name": "Launch regression",
"description": "Golden answers covering password reset and billing",
"rows": [
{
"input": "How do I reset my password?",
"expected_output": "Open Settings > Security, then choose Reset password.",
"metadata": {
"priority": "high"
}
},
{
"input": "What is my billing period?",
"expected_output": "Your billing period is the first of each month.",
"metadata": {
"priority": "medium"
}
}
]
}'
Node.js
import { Orbit } from '@devotel-orbit/node'
const orbit = new Orbit({
apiKey: process.env.ORBIT_API_KEY!,
})
const res = await fetch('https://api.orbit.devotel.io/api/v1/agents/{agentId}/evals/datasets', {
method: 'POST',
headers: {
'X-API-Key': process.env.ORBIT_API_KEY!,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "Launch regression",
"description": "Golden answers covering password reset and billing",
"rows": [
{
"input": "How do I reset my password?",
"expected_output": "Open Settings > Security, then choose Reset password.",
"metadata": {
"priority": "high"
}
},
{
"input": "What is my billing period?",
"expected_output": "Your billing period is the first of each month.",
"metadata": {
"priority": "medium"
}
}
]
}),
})
console.log(await res.json())
Python
import os, requests
headers = {"X-API-Key": os.environ["ORBIT_API_KEY"]}
headers["Content-Type"] = "application/json"
r = requests.post("https://api.orbit.devotel.io/api/v1/agents/{agentId}/evals/datasets", headers=headers, json={
"name": "Launch regression",
"description": "Golden answers covering password reset and billing",
"rows": [
{
"input": "How do I reset my password?",
"expected_output": "Open Settings > Security, then choose Reset password.",
"metadata": {
"priority": "high"
}
},
{
"input": "What is my billing period?",
"expected_output": "Your billing period is the first of each month.",
"metadata": {
"priority": "medium"
}
}
]
})
print(r.json())
Go
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("POST", "https://api.orbit.devotel.io/api/v1/agents/{agentId}/evals/datasets", bytes.NewBuffer([]byte(`{
"name": "Launch regression",
"description": "Golden answers covering password reset and billing",
"rows": [
{
"input": "How do I reset my password?",
"expected_output": "Open Settings > Security, then choose Reset password.",
"metadata": {
"priority": "high"
}
},
{
"input": "What is my billing period?",
"expected_output": "Your billing period is the first of each month.",
"metadata": {
"priority": "medium"
}
}
]
}`)))
req.Header.Set("X-API-Key", os.Getenv("ORBIT_API_KEY"))
req.Header.Set("Content-Type", "application/json")
http.DefaultClient.Do(req)
}
Ruby
require 'net/http'
require 'json'
uri = URI('https://api.orbit.devotel.io/api/v1/agents/{agentId}/evals/datasets')
req = Net::HTTP::Post.new(uri)
req['X-API-Key'] = ENV['ORBIT_API_KEY']
req['Content-Type'] = 'application/json'
req.body = {
"name": "Launch regression",
"description": "Golden answers covering password reset and billing",
"rows": [
{
"input": "How do I reset my password?",
"expected_output": "Open Settings > Security, then choose Reset password.",
"metadata": {
"priority": "high"
}
},
{
"input": "What is my billing period?",
"expected_output": "Your billing period is the first of each month.",
"metadata": {
"priority": "medium"
}
}
]
}.to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
puts res.body
PHP
<?php
$ch = curl_init('https://api.orbit.devotel.io/api/v1/agents/{agentId}/evals/datasets');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'X-API-Key: ' . getenv('ORBIT_API_KEY'),
'Content-Type: application/json',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, <<<JSON
{
"name": "Launch regression",
"description": "Golden answers covering password reset and billing",
"rows": [
{
"input": "How do I reset my password?",
"expected_output": "Open Settings > Security, then choose Reset password.",
"metadata": {
"priority": "high"
}
},
{
"input": "What is my billing period?",
"expected_output": "Your billing period is the first of each month.",
"metadata": {
"priority": "medium"
}
}
]
}
JSON);
echo curl_exec($ch);
{
"data": {
"id": "evalDs_e4f2a1",
"name": "Launch regression",
"row_count": 2,
"created_at": "2026-08-01T12:00:00.000Z"
},
"meta": {
"request_id": "req_ds_create",
"timestamp": "2026-08-01T12:00:00.000Z"
}
}
Run the eval
POST /api/v1/agents/{agentId}/evals/runsstatus: "pending" and the BullMQ worker processes each row against the agent. dataset_id and rubric_name are required. Check the run state with GET /api/v1/agents/{agentId}/evals/runs/{runId}.
Request
cURL
curl -X POST "https://api.orbit.devotel.io/api/v1/agents/{agentId}/evals/runs" \
-H "X-API-Key: dv_live_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"dataset_id": "evalDs_e4f2a1",
"rubric_name": "answer_quality",
"threshold": 80
}'
Node.js
import { Orbit } from '@devotel-orbit/node'
const orbit = new Orbit({
apiKey: process.env.ORBIT_API_KEY!,
})
const res = await fetch('https://api.orbit.devotel.io/api/v1/agents/{agentId}/evals/runs', {
method: 'POST',
headers: {
'X-API-Key': process.env.ORBIT_API_KEY!,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"dataset_id": "evalDs_e4f2a1",
"rubric_name": "answer_quality",
"threshold": 80
}),
})
console.log(await res.json())
Python
import os, requests
headers = {"X-API-Key": os.environ["ORBIT_API_KEY"]}
headers["Content-Type"] = "application/json"
r = requests.post("https://api.orbit.devotel.io/api/v1/agents/{agentId}/evals/runs", headers=headers, json={
"dataset_id": "evalDs_e4f2a1",
"rubric_name": "answer_quality",
"threshold": 80
})
print(r.json())
Go
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("POST", "https://api.orbit.devotel.io/api/v1/agents/{agentId}/evals/runs", bytes.NewBuffer([]byte(`{
"dataset_id": "evalDs_e4f2a1",
"rubric_name": "answer_quality",
"threshold": 80
}`)))
req.Header.Set("X-API-Key", os.Getenv("ORBIT_API_KEY"))
req.Header.Set("Content-Type", "application/json")
http.DefaultClient.Do(req)
}
Ruby
require 'net/http'
require 'json'
uri = URI('https://api.orbit.devotel.io/api/v1/agents/{agentId}/evals/runs')
req = Net::HTTP::Post.new(uri)
req['X-API-Key'] = ENV['ORBIT_API_KEY']
req['Content-Type'] = 'application/json'
req.body = {
"dataset_id": "evalDs_e4f2a1",
"rubric_name": "answer_quality",
"threshold": 80
}.to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
puts res.body
PHP
<?php
$ch = curl_init('https://api.orbit.devotel.io/api/v1/agents/{agentId}/evals/runs');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'X-API-Key: ' . getenv('ORBIT_API_KEY'),
'Content-Type: application/json',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, <<<JSON
{
"dataset_id": "evalDs_e4f2a1",
"rubric_name": "answer_quality",
"threshold": 80
}
JSON);
echo curl_exec($ch);
{
"data": {
"id": "run_n5x301zt",
"dataset_id": "evalDs_e4f2a1",
"rubric_name": "answer_quality",
"status": "pending",
"created_at": "2026-08-01T12:00:00.000Z"
},
"meta": {
"request_id": "req_run_launch",
"timestamp": "2026-08-01T12:00:00.000Z"
}
}
Converse with the agent
POST /api/v1/agents/{id}/chatmessage is required. Pass the conversationId from a previous reply to keep the thread going — omit it and a new conversation is created for you, its id returned on the response. When the agent grounds an answer on a bound knowledge base, the reply carries matching citations naming the documents it quoted.
Request
cURL
curl -X POST "https://api.orbit.devotel.io/api/v1/agents/{id}/chat" \
-H "X-API-Key: dv_live_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"message": "How do I reset my password?",
"conversationId": "conv_8b2c4d6e1f3a5b7c9d0e2f4a5b6c7d"
}'
Node.js
import { Orbit } from '@devotel-orbit/node'
const orbit = new Orbit({
apiKey: process.env.ORBIT_API_KEY!,
})
const res = await fetch('https://api.orbit.devotel.io/api/v1/agents/{id}/chat', {
method: 'POST',
headers: {
'X-API-Key': process.env.ORBIT_API_KEY!,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"message": "How do I reset my password?",
"conversationId": "conv_8b2c4d6e1f3a5b7c9d0e2f4a5b6c7d"
}),
})
console.log(await res.json())
Python
import os, requests
headers = {"X-API-Key": os.environ["ORBIT_API_KEY"]}
headers["Content-Type"] = "application/json"
r = requests.post("https://api.orbit.devotel.io/api/v1/agents/{id}/chat", headers=headers, json={
"message": "How do I reset my password?",
"conversationId": "conv_8b2c4d6e1f3a5b7c9d0e2f4a5b6c7d"
})
print(r.json())
Go
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("POST", "https://api.orbit.devotel.io/api/v1/agents/{id}/chat", bytes.NewBuffer([]byte(`{
"message": "How do I reset my password?",
"conversationId": "conv_8b2c4d6e1f3a5b7c9d0e2f4a5b6c7d"
}`)))
req.Header.Set("X-API-Key", os.Getenv("ORBIT_API_KEY"))
req.Header.Set("Content-Type", "application/json")
http.DefaultClient.Do(req)
}
Ruby
require 'net/http'
require 'json'
uri = URI('https://api.orbit.devotel.io/api/v1/agents/{id}/chat')
req = Net::HTTP::Post.new(uri)
req['X-API-Key'] = ENV['ORBIT_API_KEY']
req['Content-Type'] = 'application/json'
req.body = {
"message": "How do I reset my password?",
"conversationId": "conv_8b2c4d6e1f3a5b7c9d0e2f4a5b6c7d"
}.to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
puts res.body
PHP
<?php
$ch = curl_init('https://api.orbit.devotel.io/api/v1/agents/{id}/chat');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'X-API-Key: ' . getenv('ORBIT_API_KEY'),
'Content-Type: application/json',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, <<<JSON
{
"message": "How do I reset my password?",
"conversationId": "conv_8b2c4d6e1f3a5b7c9d0e2f4a5b6c7d"
}
JSON);
echo curl_exec($ch);
{
"conversationId": "conv_8b2c4d6e1f3a5b7c9d0e2f4a5b6c7d",
"response": "Open Settings > Security, then choose Reset password.",
"tokens_used": 412,
"prompt_tokens": 301,
"completion_tokens": 111,
"citations": [
{
"document_id": "doc_9a1c3e5b7d2f4a6c8e0b1d3f5a7c9e2b",
"document_name": "Account security FAQ"
}
],
"conversation_persisted": true
}
Error envelope
Most write failures return422 with the offending field named in message. Creating or updating an agent re-checks every knowledge_base_ids entry against your workspace, so a detached id — one that was deleted, or copied from another tenant — fails fast here instead of silently weakening the agent’s answers.
422
{
"error": {
"code": "INVALID_KNOWLEDGE_BASE_IDS",
"status": 422,
"message": "knowledge_base_ids reference rows that do not exist in this tenant: kb_1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e"
},
"meta": {
"request_id": "req_...",
"timestamp": "2026-08-01T12:00:00.000Z"
}
}