Skip to main content

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.

Voice API

Outbound and inbound voice calling, transcripts, and analytics Base path: /api/v1/voice Endpoint count: 17

List agent-guided call scripts for a queue

GET /api/v1/voice/queues/{id}/scripts
Returns every active script attached to the queue, ordered by name ascending. Used by the agent console at call-bridge time to render the scripted-prompts panel.
id
string
required
cURL
curl -X GET "https://api.orbit.devotel.io/api/v1/voice/queues/{id}/scripts" \
  -H "X-API-Key: dv_live_sk_your_key_here" 
Node.js
import { Orbit } from '@devotel/orbit-sdk'

const orbit = new Orbit({
  apiKey: process.env.ORBIT_API_KEY!,
})

const res = await fetch('https://api.orbit.devotel.io/api/v1/voice/queues/{id}/scripts', {
  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/voice/queues/{id}/scripts", 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/voice/queues/{id}/scripts", 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/voice/queues/{id}/scripts')
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/voice/queues/{id}/scripts');
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);

Get one queue script with its sections

GET /api/v1/voice/queues/{id}/scripts/{scriptId}
Returns the script row plus the full section tree (sorted by sort_order). The agent console renders this client-side at call-bridge time.
id
string
required
scriptId
string
required
cURL
curl -X GET "https://api.orbit.devotel.io/api/v1/voice/queues/{id}/scripts/{scriptId}" \
  -H "X-API-Key: dv_live_sk_your_key_here" 
Node.js
import { Orbit } from '@devotel/orbit-sdk'

const orbit = new Orbit({
  apiKey: process.env.ORBIT_API_KEY!,
})

const res = await fetch('https://api.orbit.devotel.io/api/v1/voice/queues/{id}/scripts/{scriptId}', {
  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/voice/queues/{id}/scripts/{scriptId}", 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/voice/queues/{id}/scripts/{scriptId}", 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/voice/queues/{id}/scripts/{scriptId}')
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/voice/queues/{id}/scripts/{scriptId}');
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);

List tenant skill catalog

GET /api/v1/voice/skill-catalog
Returns every active skill in the tenant’s catalog ordered by slug. Drives the softphone autocomplete + queue + agent edit forms. Use ?includeInactive=true for the admin catalog editor’s tombstone view.
includeInactive
string (enum: true|false)
When true, includes soft-deleted (is_active=false) rows. Default false.
cURL
curl -X GET "https://api.orbit.devotel.io/api/v1/voice/skill-catalog" \
  -H "X-API-Key: dv_live_sk_your_key_here" 
Node.js
import { Orbit } from '@devotel/orbit-sdk'

const orbit = new Orbit({
  apiKey: process.env.ORBIT_API_KEY!,
})

const res = await fetch('https://api.orbit.devotel.io/api/v1/voice/skill-catalog', {
  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/voice/skill-catalog", 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/voice/skill-catalog", 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/voice/skill-catalog')
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/voice/skill-catalog');
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);

List department voicemail boxes

GET /api/v1/voice/voicemail-boxes/
Returns every department voicemail box owned by the caller’s organization, ordered by name ascending. Each box carries its member roster and optional inbound_route_id back-ref.
cURL
curl -X GET "https://api.orbit.devotel.io/api/v1/voice/voicemail-boxes/" \
  -H "X-API-Key: dv_live_sk_your_key_here" 
Node.js
import { Orbit } from '@devotel/orbit-sdk'

const orbit = new Orbit({
  apiKey: process.env.ORBIT_API_KEY!,
})

const res = await fetch('https://api.orbit.devotel.io/api/v1/voice/voicemail-boxes/', {
  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/voice/voicemail-boxes/", 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/voice/voicemail-boxes/", 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/voice/voicemail-boxes/')
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/voice/voicemail-boxes/');
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);

Get one department voicemail box

GET /api/v1/voice/voicemail-boxes/{id}
Returns the box identified by :id when it belongs to the caller’s organization. 404 if the id does not exist or belongs to another org.
id
string
required
cURL
curl -X GET "https://api.orbit.devotel.io/api/v1/voice/voicemail-boxes/{id}" \
  -H "X-API-Key: dv_live_sk_your_key_here" 
Node.js
import { Orbit } from '@devotel/orbit-sdk'

const orbit = new Orbit({
  apiKey: process.env.ORBIT_API_KEY!,
})

const res = await fetch('https://api.orbit.devotel.io/api/v1/voice/voicemail-boxes/{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/voice/voicemail-boxes/{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/voice/voicemail-boxes/{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/voice/voicemail-boxes/{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/voice/voicemail-boxes/{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);

Mint a short-lived transcript SSE ticket

POST /api/v1/voice/calls/{callId}/transcript/ticket
Returns a 60s single-use ticket bound to (tenant, call_id) that the SSE client passes as ?ticket= on /transcript/stream. Removes the need to put a long-lived API key on the SSE URL.
callId
string
required
cURL
curl -X POST "https://api.orbit.devotel.io/api/v1/voice/calls/{callId}/transcript/ticket" \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{}'
Node.js
import { Orbit } from '@devotel/orbit-sdk'

const orbit = new Orbit({
  apiKey: process.env.ORBIT_API_KEY!,
})

const res = await fetch('https://api.orbit.devotel.io/api/v1/voice/calls/{callId}/transcript/ticket', {
  method: 'POST',
  headers: {
    'X-API-Key': process.env.ORBIT_API_KEY!,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({}),
})
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/voice/calls/{callId}/transcript/ticket", headers=headers, json={})
print(r.json())
Go
package main

import (
	"bytes"
	"net/http"
	"os"
)

func main() {
	req, _ := http.NewRequest("POST", "https://api.orbit.devotel.io/api/v1/voice/calls/{callId}/transcript/ticket", bytes.NewBuffer([]byte(`{}`)))
	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/voice/calls/{callId}/transcript/ticket')
req = Net::HTTP::Post.new(uri)
req['X-API-Key'] = ENV['ORBIT_API_KEY']
req['Content-Type'] = 'application/json'
req.body = {}.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/voice/calls/{callId}/transcript/ticket');
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
{}
JSON);
echo curl_exec($ch);

Generate AI call summary

POST /api/v1/voice/calls/{id}/summary
AI-generated structured summary; cached after first invocation.
id
string
required
cURL
curl -X POST "https://api.orbit.devotel.io/api/v1/voice/calls/{id}/summary" \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{}'
Node.js
import { Orbit } from '@devotel/orbit-sdk'

const orbit = new Orbit({
  apiKey: process.env.ORBIT_API_KEY!,
})

const res = await fetch('https://api.orbit.devotel.io/api/v1/voice/calls/{id}/summary', {
  method: 'POST',
  headers: {
    'X-API-Key': process.env.ORBIT_API_KEY!,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({}),
})
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/voice/calls/{id}/summary", headers=headers, json={})
print(r.json())
Go
package main

import (
	"bytes"
	"net/http"
	"os"
)

func main() {
	req, _ := http.NewRequest("POST", "https://api.orbit.devotel.io/api/v1/voice/calls/{id}/summary", bytes.NewBuffer([]byte(`{}`)))
	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/voice/calls/{id}/summary')
req = Net::HTTP::Post.new(uri)
req['X-API-Key'] = ENV['ORBIT_API_KEY']
req['Content-Type'] = 'application/json'
req.body = {}.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/voice/calls/{id}/summary');
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
{}
JSON);
echo curl_exec($ch);

Create a queue script

POST /api/v1/voice/queues/{id}/scripts
Creates a new script optionally with its initial section tree. Sections are full-replace on subsequent PATCHes — there is no per-section CRUD surface.
id
string
required
name
string
required
description
string | null
isActive
boolean
sections
object[]
cURL
curl -X POST "https://api.orbit.devotel.io/api/v1/voice/queues/{id}/scripts" \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "string"
}'
Node.js
import { Orbit } from '@devotel/orbit-sdk'

const orbit = new Orbit({
  apiKey: process.env.ORBIT_API_KEY!,
})

const res = await fetch('https://api.orbit.devotel.io/api/v1/voice/queues/{id}/scripts', {
  method: 'POST',
  headers: {
    'X-API-Key': process.env.ORBIT_API_KEY!,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "name": "string"
}),
})
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/voice/queues/{id}/scripts", headers=headers, json={
  "name": "string"
})
print(r.json())
Go
package main

import (
	"bytes"
	"net/http"
	"os"
)

func main() {
	req, _ := http.NewRequest("POST", "https://api.orbit.devotel.io/api/v1/voice/queues/{id}/scripts", bytes.NewBuffer([]byte(`{
  "name": "string"
}`)))
	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/voice/queues/{id}/scripts')
req = Net::HTTP::Post.new(uri)
req['X-API-Key'] = ENV['ORBIT_API_KEY']
req['Content-Type'] = 'application/json'
req.body = {
  "name": "string"
}.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/voice/queues/{id}/scripts');
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": "string"
}
JSON);
echo curl_exec($ch);

Create a tenant skill catalog row

POST /api/v1/voice/skill-catalog
Creates a new skill row. Returns 201 with the created row. A second insert of the same active slug returns 409 SKILL_SLUG_ALREADY_EXISTS.
slug
string
required
Lowercased + trimmed at the Zod boundary. UNIQUE per (org, slug) where is_active=TRUE — a duplicate active slug returns 409 SKILL_SLUG_ALREADY_EXISTS.
label
string
required
description
string
cURL
curl -X POST "https://api.orbit.devotel.io/api/v1/voice/skill-catalog" \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "slug": "string",
  "label": "string"
}'
Node.js
import { Orbit } from '@devotel/orbit-sdk'

const orbit = new Orbit({
  apiKey: process.env.ORBIT_API_KEY!,
})

const res = await fetch('https://api.orbit.devotel.io/api/v1/voice/skill-catalog', {
  method: 'POST',
  headers: {
    'X-API-Key': process.env.ORBIT_API_KEY!,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "slug": "string",
  "label": "string"
}),
})
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/voice/skill-catalog", headers=headers, json={
  "slug": "string",
  "label": "string"
})
print(r.json())
Go
package main

import (
	"bytes"
	"net/http"
	"os"
)

func main() {
	req, _ := http.NewRequest("POST", "https://api.orbit.devotel.io/api/v1/voice/skill-catalog", bytes.NewBuffer([]byte(`{
  "slug": "string",
  "label": "string"
}`)))
	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/voice/skill-catalog')
req = Net::HTTP::Post.new(uri)
req['X-API-Key'] = ENV['ORBIT_API_KEY']
req['Content-Type'] = 'application/json'
req.body = {
  "slug": "string",
  "label": "string"
}.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/voice/skill-catalog');
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
{
  "slug": "string",
  "label": "string"
}
JSON);
echo curl_exec($ch);

Create a department voicemail box

POST /api/v1/voice/voicemail-boxes/
Creates a new department voicemail box scoped to the caller’s organization. name MUST be unique within the org and is slug-shaped. Every members[*] id is validated against the org’s user roster — leaked ids from other tenants are rejected with 422. Returns 201 with the created row.
name
string
required
Slug-shape name; UNIQUE within the org.
label
string
required
members
string[]
Initial roster of subscribed user ids (max 50).
retention_days
integer | null
cURL
curl -X POST "https://api.orbit.devotel.io/api/v1/voice/voicemail-boxes/" \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "string",
  "label": "string"
}'
Node.js
import { Orbit } from '@devotel/orbit-sdk'

const orbit = new Orbit({
  apiKey: process.env.ORBIT_API_KEY!,
})

const res = await fetch('https://api.orbit.devotel.io/api/v1/voice/voicemail-boxes/', {
  method: 'POST',
  headers: {
    'X-API-Key': process.env.ORBIT_API_KEY!,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "name": "string",
  "label": "string"
}),
})
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/voice/voicemail-boxes/", headers=headers, json={
  "name": "string",
  "label": "string"
})
print(r.json())
Go
package main

import (
	"bytes"
	"net/http"
	"os"
)

func main() {
	req, _ := http.NewRequest("POST", "https://api.orbit.devotel.io/api/v1/voice/voicemail-boxes/", bytes.NewBuffer([]byte(`{
  "name": "string",
  "label": "string"
}`)))
	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/voice/voicemail-boxes/')
req = Net::HTTP::Post.new(uri)
req['X-API-Key'] = ENV['ORBIT_API_KEY']
req['Content-Type'] = 'application/json'
req.body = {
  "name": "string",
  "label": "string"
}.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/voice/voicemail-boxes/');
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": "string",
  "label": "string"
}
JSON);
echo curl_exec($ch);

Update a department voicemail box

PUT /api/v1/voice/voicemail-boxes/{id}
Partial update — only fields supplied in the body are written. members (when supplied) replaces the roster (not delta-merged); every id is re-validated against the org. Returns the persisted row.
id
string
required
name
string
label
string
members
string[]
retention_days
integer | null
cURL
curl -X PUT "https://api.orbit.devotel.io/api/v1/voice/voicemail-boxes/{id}" \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{}'
Node.js
import { Orbit } from '@devotel/orbit-sdk'

const orbit = new Orbit({
  apiKey: process.env.ORBIT_API_KEY!,
})

const res = await fetch('https://api.orbit.devotel.io/api/v1/voice/voicemail-boxes/{id}', {
  method: 'PUT',
  headers: {
    'X-API-Key': process.env.ORBIT_API_KEY!,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({}),
})
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.put("https://api.orbit.devotel.io/api/v1/voice/voicemail-boxes/{id}", headers=headers, json={})
print(r.json())
Go
package main

import (
	"bytes"
	"net/http"
	"os"
)

func main() {
	req, _ := http.NewRequest("PUT", "https://api.orbit.devotel.io/api/v1/voice/voicemail-boxes/{id}", bytes.NewBuffer([]byte(`{}`)))
	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/voice/voicemail-boxes/{id}')
req = Net::HTTP::Put.new(uri)
req['X-API-Key'] = ENV['ORBIT_API_KEY']
req['Content-Type'] = 'application/json'
req.body = {}.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/voice/voicemail-boxes/{id}');
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
{}
JSON);
echo curl_exec($ch);

Update softphone in-call notes

PATCH /api/v1/voice/calls/{id}/notes
Saves operator-typed notes onto call_logs.metadata.notes. Auto-saved by the softphone widget every 5s and on hangup.
id
string
required
notes
string
required
cURL
curl -X PATCH "https://api.orbit.devotel.io/api/v1/voice/calls/{id}/notes" \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
  "notes": "string"
}'
Node.js
import { Orbit } from '@devotel/orbit-sdk'

const orbit = new Orbit({
  apiKey: process.env.ORBIT_API_KEY!,
})

const res = await fetch('https://api.orbit.devotel.io/api/v1/voice/calls/{id}/notes', {
  method: 'PATCH',
  headers: {
    'X-API-Key': process.env.ORBIT_API_KEY!,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "notes": "string"
}),
})
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.patch("https://api.orbit.devotel.io/api/v1/voice/calls/{id}/notes", headers=headers, json={
  "notes": "string"
})
print(r.json())
Go
package main

import (
	"bytes"
	"net/http"
	"os"
)

func main() {
	req, _ := http.NewRequest("PATCH", "https://api.orbit.devotel.io/api/v1/voice/calls/{id}/notes", bytes.NewBuffer([]byte(`{
  "notes": "string"
}`)))
	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/voice/calls/{id}/notes')
req = Net::HTTP::Patch.new(uri)
req['X-API-Key'] = ENV['ORBIT_API_KEY']
req['Content-Type'] = 'application/json'
req.body = {
  "notes": "string"
}.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/voice/calls/{id}/notes');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
  'X-API-Key: ' . getenv('ORBIT_API_KEY'),
  'Content-Type: application/json',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, <<<JSON
{
  "notes": "string"
}
JSON);
echo curl_exec($ch);

Update queue script metadata and sections

PATCH /api/v1/voice/queues/{id}/scripts/{scriptId}
Partial update — only fields supplied are written. When sections is supplied it FULLY REPLACES the existing section tree (delete + insert in one transaction). Empty patch (no fields) returns 400.
id
string
required
scriptId
string
required
name
string
description
string | null
isActive
boolean
sections
object[]
cURL
curl -X PATCH "https://api.orbit.devotel.io/api/v1/voice/queues/{id}/scripts/{scriptId}" \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{}'
Node.js
import { Orbit } from '@devotel/orbit-sdk'

const orbit = new Orbit({
  apiKey: process.env.ORBIT_API_KEY!,
})

const res = await fetch('https://api.orbit.devotel.io/api/v1/voice/queues/{id}/scripts/{scriptId}', {
  method: 'PATCH',
  headers: {
    'X-API-Key': process.env.ORBIT_API_KEY!,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({}),
})
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.patch("https://api.orbit.devotel.io/api/v1/voice/queues/{id}/scripts/{scriptId}", headers=headers, json={})
print(r.json())
Go
package main

import (
	"bytes"
	"net/http"
	"os"
)

func main() {
	req, _ := http.NewRequest("PATCH", "https://api.orbit.devotel.io/api/v1/voice/queues/{id}/scripts/{scriptId}", bytes.NewBuffer([]byte(`{}`)))
	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/voice/queues/{id}/scripts/{scriptId}')
req = Net::HTTP::Patch.new(uri)
req['X-API-Key'] = ENV['ORBIT_API_KEY']
req['Content-Type'] = 'application/json'
req.body = {}.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/voice/queues/{id}/scripts/{scriptId}');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
  'X-API-Key: ' . getenv('ORBIT_API_KEY'),
  'Content-Type: application/json',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, <<<JSON
{}
JSON);
echo curl_exec($ch);

Update a tenant skill catalog row

PATCH /api/v1/voice/skill-catalog/{id}
Partial update of label, description, isActive. At least one field MUST be present. description: null clears the field; omission preserves it. Setting isActive: false soft-deletes the row.
id
string
required
label
string
description
string | null
isActive
boolean
cURL
curl -X PATCH "https://api.orbit.devotel.io/api/v1/voice/skill-catalog/{id}" \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{}'
Node.js
import { Orbit } from '@devotel/orbit-sdk'

const orbit = new Orbit({
  apiKey: process.env.ORBIT_API_KEY!,
})

const res = await fetch('https://api.orbit.devotel.io/api/v1/voice/skill-catalog/{id}', {
  method: 'PATCH',
  headers: {
    'X-API-Key': process.env.ORBIT_API_KEY!,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({}),
})
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.patch("https://api.orbit.devotel.io/api/v1/voice/skill-catalog/{id}", headers=headers, json={})
print(r.json())
Go
package main

import (
	"bytes"
	"net/http"
	"os"
)

func main() {
	req, _ := http.NewRequest("PATCH", "https://api.orbit.devotel.io/api/v1/voice/skill-catalog/{id}", bytes.NewBuffer([]byte(`{}`)))
	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/voice/skill-catalog/{id}')
req = Net::HTTP::Patch.new(uri)
req['X-API-Key'] = ENV['ORBIT_API_KEY']
req['Content-Type'] = 'application/json'
req.body = {}.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/voice/skill-catalog/{id}');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
  'X-API-Key: ' . getenv('ORBIT_API_KEY'),
  'Content-Type: application/json',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, <<<JSON
{}
JSON);
echo curl_exec($ch);

Delete a queue script

DELETE /api/v1/voice/queues/{id}/scripts/{scriptId}
Hard-deletes the script row (CASCADEs to sections via the FK). Returns 204 with no body on success; 404 if the script id does not belong to the queue.
id
string
required
scriptId
string
required
cURL
curl -X DELETE "https://api.orbit.devotel.io/api/v1/voice/queues/{id}/scripts/{scriptId}" \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{}'
Node.js
import { Orbit } from '@devotel/orbit-sdk'

const orbit = new Orbit({
  apiKey: process.env.ORBIT_API_KEY!,
})

const res = await fetch('https://api.orbit.devotel.io/api/v1/voice/queues/{id}/scripts/{scriptId}', {
  method: 'DELETE',
  headers: {
    'X-API-Key': process.env.ORBIT_API_KEY!,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({}),
})
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.delete("https://api.orbit.devotel.io/api/v1/voice/queues/{id}/scripts/{scriptId}", headers=headers, json={})
print(r.json())
Go
package main

import (
	"bytes"
	"net/http"
	"os"
)

func main() {
	req, _ := http.NewRequest("DELETE", "https://api.orbit.devotel.io/api/v1/voice/queues/{id}/scripts/{scriptId}", bytes.NewBuffer([]byte(`{}`)))
	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/voice/queues/{id}/scripts/{scriptId}')
req = Net::HTTP::Delete.new(uri)
req['X-API-Key'] = ENV['ORBIT_API_KEY']
req['Content-Type'] = 'application/json'
req.body = {}.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/voice/queues/{id}/scripts/{scriptId}');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
  'X-API-Key: ' . getenv('ORBIT_API_KEY'),
  'Content-Type: application/json',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, <<<JSON
{}
JSON);
echo curl_exec($ch);

Soft-delete a tenant skill catalog row

DELETE /api/v1/voice/skill-catalog/{id}
Soft-deletes the skill by setting is_active=false. The historical row is preserved for analytics + audit; future writes referencing the slug will fail assertSkillsRegistered. Operators may re-create the slug with a fresh row (the partial unique excludes tombstones).
id
string
required
cURL
curl -X DELETE "https://api.orbit.devotel.io/api/v1/voice/skill-catalog/{id}" \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{}'
Node.js
import { Orbit } from '@devotel/orbit-sdk'

const orbit = new Orbit({
  apiKey: process.env.ORBIT_API_KEY!,
})

const res = await fetch('https://api.orbit.devotel.io/api/v1/voice/skill-catalog/{id}', {
  method: 'DELETE',
  headers: {
    'X-API-Key': process.env.ORBIT_API_KEY!,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({}),
})
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.delete("https://api.orbit.devotel.io/api/v1/voice/skill-catalog/{id}", headers=headers, json={})
print(r.json())
Go
package main

import (
	"bytes"
	"net/http"
	"os"
)

func main() {
	req, _ := http.NewRequest("DELETE", "https://api.orbit.devotel.io/api/v1/voice/skill-catalog/{id}", bytes.NewBuffer([]byte(`{}`)))
	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/voice/skill-catalog/{id}')
req = Net::HTTP::Delete.new(uri)
req['X-API-Key'] = ENV['ORBIT_API_KEY']
req['Content-Type'] = 'application/json'
req.body = {}.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/voice/skill-catalog/{id}');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
  'X-API-Key: ' . getenv('ORBIT_API_KEY'),
  'Content-Type: application/json',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, <<<JSON
{}
JSON);
echo curl_exec($ch);

Delete a department voicemail box

DELETE /api/v1/voice/voicemail-boxes/{id}
Removes the box. Captured voicemails with box_id pointing at this row are NOT deleted — they surface under the dashboard’s Archived / orphan box group (matches user-deletion semantics for assigned_user_id). Returns 204 on success.
id
string
required
cURL
curl -X DELETE "https://api.orbit.devotel.io/api/v1/voice/voicemail-boxes/{id}" \
  -H "X-API-Key: dv_live_sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{}'
Node.js
import { Orbit } from '@devotel/orbit-sdk'

const orbit = new Orbit({
  apiKey: process.env.ORBIT_API_KEY!,
})

const res = await fetch('https://api.orbit.devotel.io/api/v1/voice/voicemail-boxes/{id}', {
  method: 'DELETE',
  headers: {
    'X-API-Key': process.env.ORBIT_API_KEY!,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({}),
})
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.delete("https://api.orbit.devotel.io/api/v1/voice/voicemail-boxes/{id}", headers=headers, json={})
print(r.json())
Go
package main

import (
	"bytes"
	"net/http"
	"os"
)

func main() {
	req, _ := http.NewRequest("DELETE", "https://api.orbit.devotel.io/api/v1/voice/voicemail-boxes/{id}", bytes.NewBuffer([]byte(`{}`)))
	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/voice/voicemail-boxes/{id}')
req = Net::HTTP::Delete.new(uri)
req['X-API-Key'] = ENV['ORBIT_API_KEY']
req['Content-Type'] = 'application/json'
req.body = {}.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/voice/voicemail-boxes/{id}');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
curl_setopt($ch, CURLOPT_HTTPHEADER, [
  'X-API-Key: ' . getenv('ORBIT_API_KEY'),
  'Content-Type: application/json',
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, <<<JSON
{}
JSON);
echo curl_exec($ch);