Preview an import before running it
curl --request POST \
--url https://api.orbit.devotel.io/api/v1/imports/{source}/dry-run \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"envelope": "enc:v1:pZ3k9x...redacted",
"entities": [
"phone_numbers",
"contacts"
],
"conversationDays": 90
}
'import requests
url = "https://api.orbit.devotel.io/api/v1/imports/{source}/dry-run"
payload = {
"envelope": "enc:v1:pZ3k9x...redacted",
"entities": ["phone_numbers", "contacts"],
"conversationDays": 90
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
envelope: 'enc:v1:pZ3k9x...redacted',
entities: ['phone_numbers', 'contacts'],
conversationDays: 90
})
};
fetch('https://api.orbit.devotel.io/api/v1/imports/{source}/dry-run', 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.orbit.devotel.io/api/v1/imports/{source}/dry-run",
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([
'envelope' => 'enc:v1:pZ3k9x...redacted',
'entities' => [
'phone_numbers',
'contacts'
],
'conversationDays' => 90
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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.orbit.devotel.io/api/v1/imports/{source}/dry-run"
payload := strings.NewReader("{\n \"envelope\": \"enc:v1:pZ3k9x...redacted\",\n \"entities\": [\n \"phone_numbers\",\n \"contacts\"\n ],\n \"conversationDays\": 90\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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.orbit.devotel.io/api/v1/imports/{source}/dry-run")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"envelope\": \"enc:v1:pZ3k9x...redacted\",\n \"entities\": [\n \"phone_numbers\",\n \"contacts\"\n ],\n \"conversationDays\": 90\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.orbit.devotel.io/api/v1/imports/{source}/dry-run")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"envelope\": \"enc:v1:pZ3k9x...redacted\",\n \"entities\": [\n \"phone_numbers\",\n \"contacts\"\n ],\n \"conversationDays\": 90\n}"
response = http.request(request)
puts response.read_body{
"data": {
"source": "twilio",
"entities": [
{
"kind": "phone_numbers",
"estimatedCount": 128,
"knownConflicts": 3
},
{
"kind": "contacts",
"estimatedCount": 5400,
"knownConflicts": 0
}
],
"etaSeconds": 60,
"generatedAt": "2026-08-15T12:00:00Z"
},
"meta": {
"request_id": "req_01J9Z8ABCDEF",
"timestamp": "2026-08-15T12:00:00Z"
}
}Imports
Preview an import before running it
Count the upstream entities and detect conflicts with existing Orbit data for the selected source, so the wizard can show an accurate ETA and conflict count before the operator commits to a run. Post the encrypted credentials envelope and the entity kinds to import (optionally capping Twilio conversation history at 90 days); nothing is written. Use this in the wizard’s “pick what to import” step, ahead of the run call.
POST
/
api
/
v1
/
imports
/
{source}
/
dry-run
Preview an import before running it
curl --request POST \
--url https://api.orbit.devotel.io/api/v1/imports/{source}/dry-run \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"envelope": "enc:v1:pZ3k9x...redacted",
"entities": [
"phone_numbers",
"contacts"
],
"conversationDays": 90
}
'import requests
url = "https://api.orbit.devotel.io/api/v1/imports/{source}/dry-run"
payload = {
"envelope": "enc:v1:pZ3k9x...redacted",
"entities": ["phone_numbers", "contacts"],
"conversationDays": 90
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
envelope: 'enc:v1:pZ3k9x...redacted',
entities: ['phone_numbers', 'contacts'],
conversationDays: 90
})
};
fetch('https://api.orbit.devotel.io/api/v1/imports/{source}/dry-run', 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.orbit.devotel.io/api/v1/imports/{source}/dry-run",
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([
'envelope' => 'enc:v1:pZ3k9x...redacted',
'entities' => [
'phone_numbers',
'contacts'
],
'conversationDays' => 90
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"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.orbit.devotel.io/api/v1/imports/{source}/dry-run"
payload := strings.NewReader("{\n \"envelope\": \"enc:v1:pZ3k9x...redacted\",\n \"entities\": [\n \"phone_numbers\",\n \"contacts\"\n ],\n \"conversationDays\": 90\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
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.orbit.devotel.io/api/v1/imports/{source}/dry-run")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"envelope\": \"enc:v1:pZ3k9x...redacted\",\n \"entities\": [\n \"phone_numbers\",\n \"contacts\"\n ],\n \"conversationDays\": 90\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.orbit.devotel.io/api/v1/imports/{source}/dry-run")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"envelope\": \"enc:v1:pZ3k9x...redacted\",\n \"entities\": [\n \"phone_numbers\",\n \"contacts\"\n ],\n \"conversationDays\": 90\n}"
response = http.request(request)
puts response.read_body{
"data": {
"source": "twilio",
"entities": [
{
"kind": "phone_numbers",
"estimatedCount": 128,
"knownConflicts": 3
},
{
"kind": "contacts",
"estimatedCount": 5400,
"knownConflicts": 0
}
],
"etaSeconds": 60,
"generatedAt": "2026-08-15T12:00:00Z"
},
"meta": {
"request_id": "req_01J9Z8ABCDEF",
"timestamp": "2026-08-15T12:00:00Z"
}
}Authorizations
BearerApiKey
Dashboard JWT token from Clerk
Path Parameters
Body
application/json
Encrypted credentials envelope returned by the connect / manual-credentials step.
Entity kinds to preview (e.g. phone_numbers, contacts, messaging_services).
Required array length:
1 - 10 elementsOptional lookback window for conversation history (Twilio caps this at 90 days).
Required range:
1 <= x <= 90⌘I