curl --request POST \
--url https://n-api.leadstaker.com/v1/calls \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"externalId": "<string>",
"phone": "<string>",
"userId": "<string>",
"startedAt": "2023-11-07T05:31:56Z",
"endedAt": "2023-11-07T05:31:56Z",
"recording": {
"base64": "<string>",
"channels": []
},
"answeredAt": "2023-11-07T05:31:56Z",
"dealId": "<string>",
"pipelineId": "<string>",
"stageId": "<string>"
}
'import requests
url = "https://n-api.leadstaker.com/v1/calls"
payload = {
"externalId": "<string>",
"phone": "<string>",
"userId": "<string>",
"startedAt": "2023-11-07T05:31:56Z",
"endedAt": "2023-11-07T05:31:56Z",
"recording": {
"base64": "<string>",
"channels": []
},
"answeredAt": "2023-11-07T05:31:56Z",
"dealId": "<string>",
"pipelineId": "<string>",
"stageId": "<string>"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
externalId: '<string>',
phone: '<string>',
userId: '<string>',
startedAt: '2023-11-07T05:31:56Z',
endedAt: '2023-11-07T05:31:56Z',
recording: {base64: '<string>', channels: []},
answeredAt: '2023-11-07T05:31:56Z',
dealId: '<string>',
pipelineId: '<string>',
stageId: '<string>'
})
};
fetch('https://n-api.leadstaker.com/v1/calls', 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://n-api.leadstaker.com/v1/calls",
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([
'externalId' => '<string>',
'phone' => '<string>',
'userId' => '<string>',
'startedAt' => '2023-11-07T05:31:56Z',
'endedAt' => '2023-11-07T05:31:56Z',
'recording' => [
'base64' => '<string>',
'channels' => [
]
],
'answeredAt' => '2023-11-07T05:31:56Z',
'dealId' => '<string>',
'pipelineId' => '<string>',
'stageId' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$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://n-api.leadstaker.com/v1/calls"
payload := strings.NewReader("{\n \"externalId\": \"<string>\",\n \"phone\": \"<string>\",\n \"userId\": \"<string>\",\n \"startedAt\": \"2023-11-07T05:31:56Z\",\n \"endedAt\": \"2023-11-07T05:31:56Z\",\n \"recording\": {\n \"base64\": \"<string>\",\n \"channels\": []\n },\n \"answeredAt\": \"2023-11-07T05:31:56Z\",\n \"dealId\": \"<string>\",\n \"pipelineId\": \"<string>\",\n \"stageId\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
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://n-api.leadstaker.com/v1/calls")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"externalId\": \"<string>\",\n \"phone\": \"<string>\",\n \"userId\": \"<string>\",\n \"startedAt\": \"2023-11-07T05:31:56Z\",\n \"endedAt\": \"2023-11-07T05:31:56Z\",\n \"recording\": {\n \"base64\": \"<string>\",\n \"channels\": []\n },\n \"answeredAt\": \"2023-11-07T05:31:56Z\",\n \"dealId\": \"<string>\",\n \"pipelineId\": \"<string>\",\n \"stageId\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://n-api.leadstaker.com/v1/calls")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"externalId\": \"<string>\",\n \"phone\": \"<string>\",\n \"userId\": \"<string>\",\n \"startedAt\": \"2023-11-07T05:31:56Z\",\n \"endedAt\": \"2023-11-07T05:31:56Z\",\n \"recording\": {\n \"base64\": \"<string>\",\n \"channels\": []\n },\n \"answeredAt\": \"2023-11-07T05:31:56Z\",\n \"dealId\": \"<string>\",\n \"pipelineId\": \"<string>\",\n \"stageId\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"id": "6abd10c5812811e995a28f1f",
"projectId": "665f1c2e8a94b70012d4e9a1",
"entityId": "6715be3a9c40aa0013d8e5c2",
"entityType": "DEAL",
"provider": "API",
"externalId": "3c-88412093",
"direction": "OUTBOUND",
"from": {
"type": "EXTENSION",
"userId": "664d9e0b7c83aa0010f1c2d3"
},
"to": {
"type": "PHONE",
"number": "5548999998888"
},
"startedAt": "2026-09-30T13:40:02.000Z",
"answeredAt": "2026-09-30T13:40:11.000Z",
"endedAt": "2026-09-30T13:42:34.000Z",
"durationInSeconds": 143,
"outcome": "ANSWERED",
"recording": {
"status": "STORED",
"mimeType": "audio/mpeg"
},
"transcription": {
"status": "PENDING"
},
"analysis": null,
"createdAt": "2026-09-30T13:42:40.000Z",
"updatedAt": "2026-09-30T13:43:15.000Z"
}{
"id": "6abd10c5812811e995a28f1f",
"projectId": "665f1c2e8a94b70012d4e9a1",
"entityId": "6715be3a9c40aa0013d8e5c2",
"entityType": "DEAL",
"provider": "API",
"externalId": "3c-88412093",
"direction": "OUTBOUND",
"from": {
"type": "EXTENSION",
"userId": "664d9e0b7c83aa0010f1c2d3"
},
"to": {
"type": "PHONE",
"number": "5548999998888"
},
"startedAt": "2026-09-30T13:40:02.000Z",
"answeredAt": "2026-09-30T13:40:11.000Z",
"endedAt": "2026-09-30T13:42:34.000Z",
"durationInSeconds": 143,
"outcome": "ANSWERED",
"recording": {
"status": "STORED",
"mimeType": "audio/mpeg"
},
"transcription": {
"status": "PENDING"
},
"analysis": null,
"createdAt": "2026-09-30T13:42:40.000Z",
"updatedAt": "2026-09-30T13:43:15.000Z"
}{
"errorCode": "<string>",
"message": "<string>",
"status": 123,
"errors": [
{
"field": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}{
"errorCode": "<string>",
"message": "<string>",
"status": 123,
"errors": [
{
"field": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}{
"errorCode": "<string>",
"message": "<string>",
"status": 123,
"errors": [
{
"field": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}{
"errorCode": "<string>",
"message": "<string>",
"status": 123,
"errors": [
{
"field": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}Post a call
Stores a finished call made on another phone system, such as a dialer, together with its audio, and gives it the same path as a call of the telephony app. The phone finds the contact and its open deal, or creates them with userId as responsible, unless dealId pins the call. Answered calls up to one hour are transcribed right away, so the call usually comes back in PENDING, and the AI analysis then writes what was said into the fields of the deal and the contact. A call without its audio is refused and nothing is created. Answers 201 with the new call, or 200 with the stored one when the externalId was posted before, without creating or uploading anything again. The body may reach about 32 MB; a larger one is refused with 413.
curl --request POST \
--url https://n-api.leadstaker.com/v1/calls \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"externalId": "<string>",
"phone": "<string>",
"userId": "<string>",
"startedAt": "2023-11-07T05:31:56Z",
"endedAt": "2023-11-07T05:31:56Z",
"recording": {
"base64": "<string>",
"channels": []
},
"answeredAt": "2023-11-07T05:31:56Z",
"dealId": "<string>",
"pipelineId": "<string>",
"stageId": "<string>"
}
'import requests
url = "https://n-api.leadstaker.com/v1/calls"
payload = {
"externalId": "<string>",
"phone": "<string>",
"userId": "<string>",
"startedAt": "2023-11-07T05:31:56Z",
"endedAt": "2023-11-07T05:31:56Z",
"recording": {
"base64": "<string>",
"channels": []
},
"answeredAt": "2023-11-07T05:31:56Z",
"dealId": "<string>",
"pipelineId": "<string>",
"stageId": "<string>"
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
externalId: '<string>',
phone: '<string>',
userId: '<string>',
startedAt: '2023-11-07T05:31:56Z',
endedAt: '2023-11-07T05:31:56Z',
recording: {base64: '<string>', channels: []},
answeredAt: '2023-11-07T05:31:56Z',
dealId: '<string>',
pipelineId: '<string>',
stageId: '<string>'
})
};
fetch('https://n-api.leadstaker.com/v1/calls', 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://n-api.leadstaker.com/v1/calls",
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([
'externalId' => '<string>',
'phone' => '<string>',
'userId' => '<string>',
'startedAt' => '2023-11-07T05:31:56Z',
'endedAt' => '2023-11-07T05:31:56Z',
'recording' => [
'base64' => '<string>',
'channels' => [
]
],
'answeredAt' => '2023-11-07T05:31:56Z',
'dealId' => '<string>',
'pipelineId' => '<string>',
'stageId' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$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://n-api.leadstaker.com/v1/calls"
payload := strings.NewReader("{\n \"externalId\": \"<string>\",\n \"phone\": \"<string>\",\n \"userId\": \"<string>\",\n \"startedAt\": \"2023-11-07T05:31:56Z\",\n \"endedAt\": \"2023-11-07T05:31:56Z\",\n \"recording\": {\n \"base64\": \"<string>\",\n \"channels\": []\n },\n \"answeredAt\": \"2023-11-07T05:31:56Z\",\n \"dealId\": \"<string>\",\n \"pipelineId\": \"<string>\",\n \"stageId\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
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://n-api.leadstaker.com/v1/calls")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"externalId\": \"<string>\",\n \"phone\": \"<string>\",\n \"userId\": \"<string>\",\n \"startedAt\": \"2023-11-07T05:31:56Z\",\n \"endedAt\": \"2023-11-07T05:31:56Z\",\n \"recording\": {\n \"base64\": \"<string>\",\n \"channels\": []\n },\n \"answeredAt\": \"2023-11-07T05:31:56Z\",\n \"dealId\": \"<string>\",\n \"pipelineId\": \"<string>\",\n \"stageId\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://n-api.leadstaker.com/v1/calls")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"externalId\": \"<string>\",\n \"phone\": \"<string>\",\n \"userId\": \"<string>\",\n \"startedAt\": \"2023-11-07T05:31:56Z\",\n \"endedAt\": \"2023-11-07T05:31:56Z\",\n \"recording\": {\n \"base64\": \"<string>\",\n \"channels\": []\n },\n \"answeredAt\": \"2023-11-07T05:31:56Z\",\n \"dealId\": \"<string>\",\n \"pipelineId\": \"<string>\",\n \"stageId\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"id": "6abd10c5812811e995a28f1f",
"projectId": "665f1c2e8a94b70012d4e9a1",
"entityId": "6715be3a9c40aa0013d8e5c2",
"entityType": "DEAL",
"provider": "API",
"externalId": "3c-88412093",
"direction": "OUTBOUND",
"from": {
"type": "EXTENSION",
"userId": "664d9e0b7c83aa0010f1c2d3"
},
"to": {
"type": "PHONE",
"number": "5548999998888"
},
"startedAt": "2026-09-30T13:40:02.000Z",
"answeredAt": "2026-09-30T13:40:11.000Z",
"endedAt": "2026-09-30T13:42:34.000Z",
"durationInSeconds": 143,
"outcome": "ANSWERED",
"recording": {
"status": "STORED",
"mimeType": "audio/mpeg"
},
"transcription": {
"status": "PENDING"
},
"analysis": null,
"createdAt": "2026-09-30T13:42:40.000Z",
"updatedAt": "2026-09-30T13:43:15.000Z"
}{
"id": "6abd10c5812811e995a28f1f",
"projectId": "665f1c2e8a94b70012d4e9a1",
"entityId": "6715be3a9c40aa0013d8e5c2",
"entityType": "DEAL",
"provider": "API",
"externalId": "3c-88412093",
"direction": "OUTBOUND",
"from": {
"type": "EXTENSION",
"userId": "664d9e0b7c83aa0010f1c2d3"
},
"to": {
"type": "PHONE",
"number": "5548999998888"
},
"startedAt": "2026-09-30T13:40:02.000Z",
"answeredAt": "2026-09-30T13:40:11.000Z",
"endedAt": "2026-09-30T13:42:34.000Z",
"durationInSeconds": 143,
"outcome": "ANSWERED",
"recording": {
"status": "STORED",
"mimeType": "audio/mpeg"
},
"transcription": {
"status": "PENDING"
},
"analysis": null,
"createdAt": "2026-09-30T13:42:40.000Z",
"updatedAt": "2026-09-30T13:43:15.000Z"
}{
"errorCode": "<string>",
"message": "<string>",
"status": 123,
"errors": [
{
"field": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}{
"errorCode": "<string>",
"message": "<string>",
"status": 123,
"errors": [
{
"field": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}{
"errorCode": "<string>",
"message": "<string>",
"status": 123,
"errors": [
{
"field": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}{
"errorCode": "<string>",
"message": "<string>",
"status": 123,
"errors": [
{
"field": "<string>",
"code": "<string>",
"message": "<string>"
}
]
}Authorizations
Body
The call id in your system. Posting it again returns the stored call instead of a second one.
1 - 200OUTBOUND when the salesperson placed the call, INBOUND when the lead did.
OUTBOUND, INBOUND The lead phone with its country code, e.g. 5548999998888. It finds the contact, or creates one.
1The project member who talked. Responsible for the contact and deal the call creates.
1^[a-f\d]{24}$ISO 8601 instant with an explicit offset, e.g. 2026-10-21T14:05:00-03:00.
ISO 8601 instant with an explicit offset, e.g. 2026-10-21T14:05:00-03:00.
ANSWERED, NO_ANSWER, BUSY, VOICEMAIL, FAILED Required: a call is never stored without its audio.
Show child attributes
Show child attributes
Absent when nobody answered. The talk time runs from here to endedAt.
Attaches the call to this deal. Without it the phone decides: the contact's open deal, or a new one.
1^[a-f\d]{24}$Where a deal the call creates starts. Send it with stageId; without both, the first open stage of the oldest pipeline.
1^[a-f\d]{24}$An open stage of pipelineId.
1Response
Success
11The deal the call is attached to, or the contact when it has no deal.
1DEAL, CONTACT The telephony provider, or API for a call posted to POST /calls.
API4COM, API The call id on the telephony provider, or in the system that posted it.
1OUTBOUND, INBOUND - Option 1
- Option 2
Show child attributes
Show child attributes
- Option 1
- Option 2
Show child attributes
Show child attributes
Talk time, from the answer to the hang up.
ANSWERED, NO_ANSWER, BUSY, VOICEMAIL, FAILED Show child attributes
Show child attributes
Null while there is no stored recording.
Show child attributes
Show child attributes
The AI summary, written after each transcription; null before the first one.
Show child attributes
Show child attributes