Documentation Index
Fetch the complete documentation index at: https://orbit-docs.devotel.io/llms.txt
Use this file to discover all available pages before exploring further.
Contacts API
Manage your contact database with full CRUD operations, tagging, list membership, dynamic segments, and per-channel opt-in/opt-out preferences.
Base path: /v1/contacts
POST /v1/contacts
Add a new contact to your account.
Phone number in E.164 format (e.g., +14155552671)
ISO 3166-1 alpha-2 country code (e.g., US, TR)
Contact lifecycle stage: lead, customer, churned, etc.
Custom key-value data attached to the contact
curl -X POST "https://orbit-api.devotel.io/api/v1/contacts" \
-H "X-API-Key: dv_live_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"phone": "+14155552671",
"email": "jane@example.com",
"first_name": "Jane",
"last_name": "Doe",
"country_code": "US",
"lifecycle_stage": "lead",
"tags": [
"beta-tester"
]
}'
import { Orbit } from '@devotel/orbit-sdk'
const orbit = new Orbit({
apiKey: process.env.ORBIT_API_KEY!,
})
const res = await fetch('https://orbit-api.devotel.io/api/v1/contacts', {
method: 'POST',
headers: {
'X-API-Key': process.env.ORBIT_API_KEY!,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"phone": "+14155552671",
"email": "jane@example.com",
"first_name": "Jane",
"last_name": "Doe",
"country_code": "US",
"lifecycle_stage": "lead",
"tags": [
"beta-tester"
]
}),
})
console.log(await res.json())
import os, requests
headers = {"X-API-Key": os.environ["ORBIT_API_KEY"]}
headers["Content-Type"] = "application/json"
r = requests.post("https://orbit-api.devotel.io/api/v1/contacts", headers=headers, json={
"phone": "+14155552671",
"email": "jane@example.com",
"first_name": "Jane",
"last_name": "Doe",
"country_code": "US",
"lifecycle_stage": "lead",
"tags": [
"beta-tester"
]
})
print(r.json())
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("POST", "https://orbit-api.devotel.io/api/v1/contacts", bytes.NewBuffer([]byte(`{
"phone": "+14155552671",
"email": "jane@example.com",
"first_name": "Jane",
"last_name": "Doe",
"country_code": "US",
"lifecycle_stage": "lead",
"tags": [
"beta-tester"
]
}`)))
req.Header.Set("X-API-Key", os.Getenv("ORBIT_API_KEY"))
req.Header.Set("Content-Type", "application/json")
http.DefaultClient.Do(req)
}
require 'net/http'
require 'json'
uri = URI('https://orbit-api.devotel.io/api/v1/contacts')
req = Net::HTTP::Post.new(uri)
req['X-API-Key'] = ENV['ORBIT_API_KEY']
req['Content-Type'] = 'application/json'
req.body = {
"phone": "+14155552671",
"email": "jane@example.com",
"first_name": "Jane",
"last_name": "Doe",
"country_code": "US",
"lifecycle_stage": "lead",
"tags": [
"beta-tester"
]
}.to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
puts res.body
<?php
$ch = curl_init('https://orbit-api.devotel.io/api/v1/contacts');
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
{
"phone": "+14155552671",
"email": "jane@example.com",
"first_name": "Jane",
"last_name": "Doe",
"country_code": "US",
"lifecycle_stage": "lead",
"tags": [
"beta-tester"
]
}
JSON);
echo curl_exec($ch);
{
"data": {
"id": "con_abc123",
"phone": "+14155552671",
"email": "jane@example.com",
"first_name": "Jane",
"last_name": "Doe",
"country_code": "US",
"lifecycle_stage": "lead",
"tags": ["beta-tester"],
"created_at": "2026-03-08T12:00:00Z"
},
"meta": {
"request_id": "req_con_001",
"timestamp": "2026-03-08T12:00:00Z"
}
}
GET /v1/contacts
Retrieve contacts with search, filtering, and cursor-based pagination.
Number of results per page (max 100)
Full-text search across name, phone, and email
Filter by lifecycle stage
curl -X GET "https://orbit-api.devotel.io/api/v1/contacts?search=jane&lifecycle_stage=lead&limit=20" \
-H "X-API-Key: dv_live_sk_your_key_here"
import { Orbit } from '@devotel/orbit-sdk'
const orbit = new Orbit({
apiKey: process.env.ORBIT_API_KEY!,
})
const res = await fetch('https://orbit-api.devotel.io/api/v1/contacts?search=jane&lifecycle_stage=lead&limit=20', {
method: 'GET',
headers: {
'X-API-Key': process.env.ORBIT_API_KEY!,
},
})
console.log(await res.json())
import os, requests
headers = {"X-API-Key": os.environ["ORBIT_API_KEY"]}
r = requests.get("https://orbit-api.devotel.io/api/v1/contacts?search=jane&lifecycle_stage=lead&limit=20", headers=headers)
print(r.json())
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://orbit-api.devotel.io/api/v1/contacts?search=jane&lifecycle_stage=lead&limit=20", nil)
req.Header.Set("X-API-Key", os.Getenv("ORBIT_API_KEY"))
http.DefaultClient.Do(req)
}
require 'net/http'
require 'json'
uri = URI('https://orbit-api.devotel.io/api/v1/contacts?search=jane&lifecycle_stage=lead&limit=20')
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
$ch = curl_init('https://orbit-api.devotel.io/api/v1/contacts?search=jane&lifecycle_stage=lead&limit=20');
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": "con_abc123",
"phone": "+14155552671",
"email": "jane@example.com",
"first_name": "Jane",
"last_name": "Doe",
"lifecycle_stage": "lead",
"tags": ["beta-tester"]
}
],
"meta": {
"request_id": "req_list_con",
"timestamp": "2026-03-08T12:00:00Z",
"pagination": {
"cursor": "cur_con_abc",
"has_more": true,
"total": 4230
}
}
}
GET /v1/contacts/{id}
Retrieve a single contact by ID.
Contact ID (e.g., con_abc123)
PUT /v1/contacts/{id}
Update one or more fields on an existing contact.
Updated phone number (E.164)
Updated custom metadata (merged with existing)
DELETE /v1/contacts/{id}
Permanently remove a contact and all associated data.
Response: 204 No Content
POST /v1/contacts/{id}/tags
Append one or more tags to a contact. Duplicate tags are ignored.
Array of tag strings to add
curl -X POST "https://orbit-api.devotel.io/api/v1/contacts/con_abc123/tags" \
-H "X-API-Key: dv_live_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"tags": [
"vip",
"enterprise"
]
}'
import { Orbit } from '@devotel/orbit-sdk'
const orbit = new Orbit({
apiKey: process.env.ORBIT_API_KEY!,
})
const res = await fetch('https://orbit-api.devotel.io/api/v1/contacts/con_abc123/tags', {
method: 'POST',
headers: {
'X-API-Key': process.env.ORBIT_API_KEY!,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"tags": [
"vip",
"enterprise"
]
}),
})
console.log(await res.json())
import os, requests
headers = {"X-API-Key": os.environ["ORBIT_API_KEY"]}
headers["Content-Type"] = "application/json"
r = requests.post("https://orbit-api.devotel.io/api/v1/contacts/con_abc123/tags", headers=headers, json={
"tags": [
"vip",
"enterprise"
]
})
print(r.json())
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("POST", "https://orbit-api.devotel.io/api/v1/contacts/con_abc123/tags", bytes.NewBuffer([]byte(`{
"tags": [
"vip",
"enterprise"
]
}`)))
req.Header.Set("X-API-Key", os.Getenv("ORBIT_API_KEY"))
req.Header.Set("Content-Type", "application/json")
http.DefaultClient.Do(req)
}
require 'net/http'
require 'json'
uri = URI('https://orbit-api.devotel.io/api/v1/contacts/con_abc123/tags')
req = Net::HTTP::Post.new(uri)
req['X-API-Key'] = ENV['ORBIT_API_KEY']
req['Content-Type'] = 'application/json'
req.body = {
"tags": [
"vip",
"enterprise"
]
}.to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
puts res.body
<?php
$ch = curl_init('https://orbit-api.devotel.io/api/v1/contacts/con_abc123/tags');
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
{
"tags": [
"vip",
"enterprise"
]
}
JSON);
echo curl_exec($ch);
{
"data": {
"id": "con_abc123",
"tags": ["beta-tester", "vip", "enterprise"]
},
"meta": {
"request_id": "req_tag_001",
"timestamp": "2026-03-08T12:00:00Z"
}
}
Remove Tag
DELETE /v1/contacts/{id}/tags/{tag}
Remove a single tag from a contact.
Activity Timeline
GET /v1/contacts/{id}/activity
Retrieve the communication timeline for a contact — messages sent, delivered, opened, and agent interactions.
{
"data": [
{
"type": "message.delivered",
"channel": "sms",
"message_id": "msg_001",
"timestamp": "2026-03-08T11:30:00Z"
},
{
"type": "message.sent",
"channel": "whatsapp",
"message_id": "msg_002",
"timestamp": "2026-03-08T10:00:00Z"
}
],
"meta": {
"request_id": "req_act_001",
"timestamp": "2026-03-08T12:00:00Z"
}
}
Channel Preferences
PUT /v1/contacts/{id}/preferences
Update a contact’s per-channel opt-in/opt-out preferences.
curl -X PUT "https://orbit-api.devotel.io/api/v1/contacts/con_abc123/preferences" \
-H "X-API-Key: dv_live_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"preferences": {
"sms": true,
"whatsapp": true,
"email": false
}
}'
import { Orbit } from '@devotel/orbit-sdk'
const orbit = new Orbit({
apiKey: process.env.ORBIT_API_KEY!,
})
const res = await fetch('https://orbit-api.devotel.io/api/v1/contacts/con_abc123/preferences', {
method: 'PUT',
headers: {
'X-API-Key': process.env.ORBIT_API_KEY!,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"preferences": {
"sms": true,
"whatsapp": true,
"email": false
}
}),
})
console.log(await res.json())
import os, requests
headers = {"X-API-Key": os.environ["ORBIT_API_KEY"]}
headers["Content-Type"] = "application/json"
r = requests.put("https://orbit-api.devotel.io/api/v1/contacts/con_abc123/preferences", headers=headers, json={
"preferences": {
"sms": true,
"whatsapp": true,
"email": false
}
})
print(r.json())
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("PUT", "https://orbit-api.devotel.io/api/v1/contacts/con_abc123/preferences", bytes.NewBuffer([]byte(`{
"preferences": {
"sms": true,
"whatsapp": true,
"email": false
}
}`)))
req.Header.Set("X-API-Key", os.Getenv("ORBIT_API_KEY"))
req.Header.Set("Content-Type", "application/json")
http.DefaultClient.Do(req)
}
require 'net/http'
require 'json'
uri = URI('https://orbit-api.devotel.io/api/v1/contacts/con_abc123/preferences')
req = Net::HTTP::Put.new(uri)
req['X-API-Key'] = ENV['ORBIT_API_KEY']
req['Content-Type'] = 'application/json'
req.body = {
"preferences": {
"sms": true,
"whatsapp": true,
"email": false
}
}.to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
puts res.body
<?php
$ch = curl_init('https://orbit-api.devotel.io/api/v1/contacts/con_abc123/preferences');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'X-API-Key: ' . getenv('ORBIT_API_KEY'),
'Content-Type: application/json',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, <<<JSON
{
"preferences": {
"sms": true,
"whatsapp": true,
"email": false
}
}
JSON);
echo curl_exec($ch);
Opt-outs
GET /v1/contacts/optouts
List all contacts who have opted out of one or more channels.
Number of results per page (max 100)
Filter opt-outs by channel: sms, whatsapp, email, rcs, viber, voice
Search by name, phone, or email
Lists
List All Lists
GET /v1/contacts/lists
Retrieve all contact lists.
Create List
POST /v1/contacts/lists
Create a new contact list.
curl -X POST "https://orbit-api.devotel.io/api/v1/contacts/lists" \
-H "X-API-Key: dv_live_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"name": "VIP Customers",
"description": "High-value accounts"
}'
import { Orbit } from '@devotel/orbit-sdk'
const orbit = new Orbit({
apiKey: process.env.ORBIT_API_KEY!,
})
const res = await fetch('https://orbit-api.devotel.io/api/v1/contacts/lists', {
method: 'POST',
headers: {
'X-API-Key': process.env.ORBIT_API_KEY!,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "VIP Customers",
"description": "High-value accounts"
}),
})
console.log(await res.json())
import os, requests
headers = {"X-API-Key": os.environ["ORBIT_API_KEY"]}
headers["Content-Type"] = "application/json"
r = requests.post("https://orbit-api.devotel.io/api/v1/contacts/lists", headers=headers, json={
"name": "VIP Customers",
"description": "High-value accounts"
})
print(r.json())
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("POST", "https://orbit-api.devotel.io/api/v1/contacts/lists", bytes.NewBuffer([]byte(`{
"name": "VIP Customers",
"description": "High-value accounts"
}`)))
req.Header.Set("X-API-Key", os.Getenv("ORBIT_API_KEY"))
req.Header.Set("Content-Type", "application/json")
http.DefaultClient.Do(req)
}
require 'net/http'
require 'json'
uri = URI('https://orbit-api.devotel.io/api/v1/contacts/lists')
req = Net::HTTP::Post.new(uri)
req['X-API-Key'] = ENV['ORBIT_API_KEY']
req['Content-Type'] = 'application/json'
req.body = {
"name": "VIP Customers",
"description": "High-value accounts"
}.to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
puts res.body
<?php
$ch = curl_init('https://orbit-api.devotel.io/api/v1/contacts/lists');
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": "VIP Customers",
"description": "High-value accounts"
}
JSON);
echo curl_exec($ch);
{
"data": {
"id": "lst_abc123",
"name": "VIP Customers",
"description": "High-value accounts",
"member_count": 0,
"created_at": "2026-03-08T12:00:00Z"
},
"meta": {
"request_id": "req_lst_001",
"timestamp": "2026-03-08T12:00:00Z"
}
}
Update List
PUT /v1/contacts/lists/{id}
Update a contact list’s name or description.
Delete List
DELETE /v1/contacts/lists/{id}
Delete a contact list. Members are not deleted — only the list association is removed.
Response: 204 No Content
List Members
GET /v1/contacts/lists/{id}/members
List contacts belonging to a specific list (cursor-paginated).
Number of results per page (max 100)
Segments
List Segments
GET /v1/contacts/segments
Retrieve all dynamic contact segments with cursor-based pagination.
Number of results per page (max 100)
Create Segment
POST /v1/contacts/segments
Create a new dynamic segment with filter rules.
Filter rules object that defines which contacts belong to this segment
curl -X POST "https://orbit-api.devotel.io/api/v1/contacts/segments" \
-H "X-API-Key: dv_live_sk_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"name": "US Enterprise Leads",
"rules": {
"country_code": "US",
"lifecycle_stage": "lead",
"tags": {
"$contains": "enterprise"
}
}
}'
import { Orbit } from '@devotel/orbit-sdk'
const orbit = new Orbit({
apiKey: process.env.ORBIT_API_KEY!,
})
const res = await fetch('https://orbit-api.devotel.io/api/v1/contacts/segments', {
method: 'POST',
headers: {
'X-API-Key': process.env.ORBIT_API_KEY!,
'Content-Type': 'application/json',
},
body: JSON.stringify({
"name": "US Enterprise Leads",
"rules": {
"country_code": "US",
"lifecycle_stage": "lead",
"tags": {
"$contains": "enterprise"
}
}
}),
})
console.log(await res.json())
import os, requests
headers = {"X-API-Key": os.environ["ORBIT_API_KEY"]}
headers["Content-Type"] = "application/json"
r = requests.post("https://orbit-api.devotel.io/api/v1/contacts/segments", headers=headers, json={
"name": "US Enterprise Leads",
"rules": {
"country_code": "US",
"lifecycle_stage": "lead",
"tags": {
"$contains": "enterprise"
}
}
})
print(r.json())
package main
import (
"bytes"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("POST", "https://orbit-api.devotel.io/api/v1/contacts/segments", bytes.NewBuffer([]byte(`{
"name": "US Enterprise Leads",
"rules": {
"country_code": "US",
"lifecycle_stage": "lead",
"tags": {
"$contains": "enterprise"
}
}
}`)))
req.Header.Set("X-API-Key", os.Getenv("ORBIT_API_KEY"))
req.Header.Set("Content-Type", "application/json")
http.DefaultClient.Do(req)
}
require 'net/http'
require 'json'
uri = URI('https://orbit-api.devotel.io/api/v1/contacts/segments')
req = Net::HTTP::Post.new(uri)
req['X-API-Key'] = ENV['ORBIT_API_KEY']
req['Content-Type'] = 'application/json'
req.body = {
"name": "US Enterprise Leads",
"rules": {
"country_code": "US",
"lifecycle_stage": "lead",
"tags": {
"$contains": "enterprise"
}
}
}.to_json
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
puts res.body
<?php
$ch = curl_init('https://orbit-api.devotel.io/api/v1/contacts/segments');
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": "US Enterprise Leads",
"rules": {
"country_code": "US",
"lifecycle_stage": "lead",
"tags": {
"$contains": "enterprise"
}
}
}
JSON);
echo curl_exec($ch);
{
"data": {
"id": "seg_abc123",
"name": "US Enterprise Leads",
"rules": {
"country_code": "US",
"lifecycle_stage": "lead",
"tags": { "$contains": "enterprise" }
},
"contact_count": 142,
"created_at": "2026-03-08T12:00:00Z"
},
"meta": {
"request_id": "req_seg_001",
"timestamp": "2026-03-08T12:00:00Z"
}
}
Delete Segment
DELETE /v1/contacts/segments/{id}
Delete a dynamic segment. Contacts are not affected.
Response: 204 No Content