Bulk Initiate Leads
curl --request POST \
--url https://crm.uservox.ai/api/v1/leads/bulk/initiate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"leadIds": [
"<string>"
],
"leads": [
{
"projectId": "<string>",
"processId": "<string>",
"groupId": "<string>",
"phone": "<string>",
"email": "<string>",
"name": "<string>",
"firstName": "<string>",
"lastName": "<string>",
"referenceId": "<string>",
"metadata": {}
}
],
"init": true
}
'import requests
url = "https://crm.uservox.ai/api/v1/leads/bulk/initiate"
payload = {
"leadIds": ["<string>"],
"leads": [
{
"projectId": "<string>",
"processId": "<string>",
"groupId": "<string>",
"phone": "<string>",
"email": "<string>",
"name": "<string>",
"firstName": "<string>",
"lastName": "<string>",
"referenceId": "<string>",
"metadata": {}
}
],
"init": True
}
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({
leadIds: ['<string>'],
leads: [
{
projectId: '<string>',
processId: '<string>',
groupId: '<string>',
phone: '<string>',
email: '<string>',
name: '<string>',
firstName: '<string>',
lastName: '<string>',
referenceId: '<string>',
metadata: {}
}
],
init: true
})
};
fetch('https://crm.uservox.ai/api/v1/leads/bulk/initiate', 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://crm.uservox.ai/api/v1/leads/bulk/initiate",
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([
'leadIds' => [
'<string>'
],
'leads' => [
[
'projectId' => '<string>',
'processId' => '<string>',
'groupId' => '<string>',
'phone' => '<string>',
'email' => '<string>',
'name' => '<string>',
'firstName' => '<string>',
'lastName' => '<string>',
'referenceId' => '<string>',
'metadata' => [
]
]
],
'init' => true
]),
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://crm.uservox.ai/api/v1/leads/bulk/initiate"
payload := strings.NewReader("{\n \"leadIds\": [\n \"<string>\"\n ],\n \"leads\": [\n {\n \"projectId\": \"<string>\",\n \"processId\": \"<string>\",\n \"groupId\": \"<string>\",\n \"phone\": \"<string>\",\n \"email\": \"<string>\",\n \"name\": \"<string>\",\n \"firstName\": \"<string>\",\n \"lastName\": \"<string>\",\n \"referenceId\": \"<string>\",\n \"metadata\": {}\n }\n ],\n \"init\": true\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://crm.uservox.ai/api/v1/leads/bulk/initiate")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"leadIds\": [\n \"<string>\"\n ],\n \"leads\": [\n {\n \"projectId\": \"<string>\",\n \"processId\": \"<string>\",\n \"groupId\": \"<string>\",\n \"phone\": \"<string>\",\n \"email\": \"<string>\",\n \"name\": \"<string>\",\n \"firstName\": \"<string>\",\n \"lastName\": \"<string>\",\n \"referenceId\": \"<string>\",\n \"metadata\": {}\n }\n ],\n \"init\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://crm.uservox.ai/api/v1/leads/bulk/initiate")
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 \"leadIds\": [\n \"<string>\"\n ],\n \"leads\": [\n {\n \"projectId\": \"<string>\",\n \"processId\": \"<string>\",\n \"groupId\": \"<string>\",\n \"phone\": \"<string>\",\n \"email\": \"<string>\",\n \"name\": \"<string>\",\n \"firstName\": \"<string>\",\n \"lastName\": \"<string>\",\n \"referenceId\": \"<string>\",\n \"metadata\": {}\n }\n ],\n \"init\": true\n}"
response = http.request(request)
puts response.read_body{
"success": [
{}
],
"errors": [
{
"data": {},
"referenceId": "<string>",
"error": "<string>"
}
]
}Leads
Bulk Initiate Leads
Create or validate multiple leads in a single request and optionally start initialization
POST
/
leads
/
bulk
/
initiate
Bulk Initiate Leads
curl --request POST \
--url https://crm.uservox.ai/api/v1/leads/bulk/initiate \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"leadIds": [
"<string>"
],
"leads": [
{
"projectId": "<string>",
"processId": "<string>",
"groupId": "<string>",
"phone": "<string>",
"email": "<string>",
"name": "<string>",
"firstName": "<string>",
"lastName": "<string>",
"referenceId": "<string>",
"metadata": {}
}
],
"init": true
}
'import requests
url = "https://crm.uservox.ai/api/v1/leads/bulk/initiate"
payload = {
"leadIds": ["<string>"],
"leads": [
{
"projectId": "<string>",
"processId": "<string>",
"groupId": "<string>",
"phone": "<string>",
"email": "<string>",
"name": "<string>",
"firstName": "<string>",
"lastName": "<string>",
"referenceId": "<string>",
"metadata": {}
}
],
"init": True
}
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({
leadIds: ['<string>'],
leads: [
{
projectId: '<string>',
processId: '<string>',
groupId: '<string>',
phone: '<string>',
email: '<string>',
name: '<string>',
firstName: '<string>',
lastName: '<string>',
referenceId: '<string>',
metadata: {}
}
],
init: true
})
};
fetch('https://crm.uservox.ai/api/v1/leads/bulk/initiate', 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://crm.uservox.ai/api/v1/leads/bulk/initiate",
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([
'leadIds' => [
'<string>'
],
'leads' => [
[
'projectId' => '<string>',
'processId' => '<string>',
'groupId' => '<string>',
'phone' => '<string>',
'email' => '<string>',
'name' => '<string>',
'firstName' => '<string>',
'lastName' => '<string>',
'referenceId' => '<string>',
'metadata' => [
]
]
],
'init' => true
]),
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://crm.uservox.ai/api/v1/leads/bulk/initiate"
payload := strings.NewReader("{\n \"leadIds\": [\n \"<string>\"\n ],\n \"leads\": [\n {\n \"projectId\": \"<string>\",\n \"processId\": \"<string>\",\n \"groupId\": \"<string>\",\n \"phone\": \"<string>\",\n \"email\": \"<string>\",\n \"name\": \"<string>\",\n \"firstName\": \"<string>\",\n \"lastName\": \"<string>\",\n \"referenceId\": \"<string>\",\n \"metadata\": {}\n }\n ],\n \"init\": true\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://crm.uservox.ai/api/v1/leads/bulk/initiate")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"leadIds\": [\n \"<string>\"\n ],\n \"leads\": [\n {\n \"projectId\": \"<string>\",\n \"processId\": \"<string>\",\n \"groupId\": \"<string>\",\n \"phone\": \"<string>\",\n \"email\": \"<string>\",\n \"name\": \"<string>\",\n \"firstName\": \"<string>\",\n \"lastName\": \"<string>\",\n \"referenceId\": \"<string>\",\n \"metadata\": {}\n }\n ],\n \"init\": true\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://crm.uservox.ai/api/v1/leads/bulk/initiate")
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 \"leadIds\": [\n \"<string>\"\n ],\n \"leads\": [\n {\n \"projectId\": \"<string>\",\n \"processId\": \"<string>\",\n \"groupId\": \"<string>\",\n \"phone\": \"<string>\",\n \"email\": \"<string>\",\n \"name\": \"<string>\",\n \"firstName\": \"<string>\",\n \"lastName\": \"<string>\",\n \"referenceId\": \"<string>\",\n \"metadata\": {}\n }\n ],\n \"init\": true\n}"
response = http.request(request)
puts response.read_body{
"success": [
{}
],
"errors": [
{
"data": {},
"referenceId": "<string>",
"error": "<string>"
}
]
}Rate Limits:
- Request Rate: ~100 requests per 5 seconds per project
- Maximum Leads: 1000 leads per request
Body Parameters
string[]
Array of existing lead IDs (required if
leads not provided)object[]
Array of new lead objects (required if
leadIds not provided)Show Lead Object Properties
Show Lead Object Properties
string
required
MongoDB ObjectId of the project
string
required
MongoDB ObjectId of the process
string
Optional ID to group leads for analytics
string
Phone number (required if email not provided)
string
Email address (required if phone not provided)
string
Full name (required if firstName not provided)
string
First name (required if name not provided)
string
Last name
string
External reference ID
object
Additional metadata
boolean
default:"true"
Whether to initialize leads for calling
Query Parameters
string
API version. Use
"1.2" for simplified response formatResponse
array
Array of successfully created/validated leads
array
Error Responses
-
400 Bad Request
- Missing body / wrong type
- Returned when neither
leadIdsnorleadsis provided, or when the value is not an array. - Examples:
{ "error": "Either leadIds or leads array is required" }{ "error": "Input must be an array" }
- Returned when neither
- Too many leads
- Returned when the number of items exceeds the maximum per request.
- Example:
{ "error": "Maximum of 1000 leads allowed per request" }(limit may be overridden by config).
- Per-lead validation errors / bad leads
- Individual leads that fail validation (duplicate, bad phone, etc.) are reported in the
errorsarray. - Typical messages include:
"A call attempt has already been made to this phone number for this project""Phone number contains repeating digits pattern""already exists for this project and process"
- These indicate bad/invalid leads. Do not retry these specific leads via this API.
- Recommended behavior:
- Mark those leads as invalid in your system.
- Fix the underlying data (phone number, process, etc.) before attempting again as new leads.
- Individual leads that fail validation (duplicate, bad phone, etc.) are reported in the
- Missing body / wrong type
-
403 Forbidden
- Returned when some leads have missing or invalid
projectIdrelative to the authenticated project. - Example:
{ "error": "Some leads have missing or invalid projectId", "invalidLeads": [ { "data": { ... }, "error": "missing projectId" }, { "data": { ... }, "error": "projectId does not match authenticated project" } ] } - Also returned when the target project is inactive or not found.
- Returned when some leads have missing or invalid
-
404 Not Found
- Returned when a
processIdin theleadsarray does not exist. - Example:
{ "error": "Process not found for lead with processId: <id>" }
- Returned when a
-
429 Too Many Requests
- Bulk initiate uses the same project-level rate limiting and duplicate protection as the single-lead initiate API.
- If you continuously send duplicate or bad data, your API key may be temporarily blocked.
- Do not keep retrying the same bad leads, as this can cause more 429s and longer blocks.
-
500 Internal Server Error
- Unexpected server-side error.
- Safe to retry with exponential backoff only for 5xx responses (not for 4xx).
Retry Guidance
- Do not retry bad leads
- Any per-lead validation/duplicate errors returned in the
errorsarray should be treated as permanent failures for those payloads. - Re-sending the same bad lead can:
- Trigger duplicate-protection limits.
- Lead to
429blocks for your API key.
- Any per-lead validation/duplicate errors returned in the
- When to retry
- It is acceptable to implement retries (with backoff) for:
- Network errors.
- 5xx responses (
500and other server errors).
- Do not automatically retry on 4xx responses; fix the request or underlying data instead.
- It is acceptable to implement retries (with backoff) for:
