curl --request GET \
--url https://api.peachdeskai.com/api/v1/sequences/{sequence_id}/contacts/import \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.peachdeskai.com/api/v1/sequences/{sequence_id}/contacts/import"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.peachdeskai.com/api/v1/sequences/{sequence_id}/contacts/import', 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.peachdeskai.com/api/v1/sequences/{sequence_id}/contacts/import",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.peachdeskai.com/api/v1/sequences/{sequence_id}/contacts/import"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.peachdeskai.com/api/v1/sequences/{sequence_id}/contacts/import")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.peachdeskai.com/api/v1/sequences/{sequence_id}/contacts/import")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"import_id": 123,
"status": "<string>",
"started_at": "2023-11-07T05:31:56Z",
"completed_at": "2023-11-07T05:31:56Z",
"source_type": "<string>",
"rows_read": 123,
"rows_accepted": 123,
"rows_rejected": 123,
"failure_reason": "<string>",
"rejections_by_reason": {},
"rejections": [
{
"import_id": 123,
"row_number": 123,
"reason_code": "<string>",
"rejected_value": "<string>"
}
],
"totals": {
"imports": 0,
"rows_read": 0,
"accepted": 0,
"rejected": 0
},
"totals_rejections_by_reason": {},
"imports": [
{
"id": 123,
"status": "<string>",
"completed_at": "2023-11-07T05:31:56Z",
"rows_read": 123,
"rows_accepted": 123,
"rows_rejected": 123,
"failure_reason": "<string>"
}
]
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Get Latest Contact Import
What the last read of this sequenceтАЩs contact source did.
Every read here is tenant-scoped in the query and not merely behind the 404 above: the rejection rows carry the customerтАЩs phone numbers by design, so this is a contact read and takes a contact readтАЩs scoping.
curl --request GET \
--url https://api.peachdeskai.com/api/v1/sequences/{sequence_id}/contacts/import \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.peachdeskai.com/api/v1/sequences/{sequence_id}/contacts/import"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.peachdeskai.com/api/v1/sequences/{sequence_id}/contacts/import', 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.peachdeskai.com/api/v1/sequences/{sequence_id}/contacts/import",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.peachdeskai.com/api/v1/sequences/{sequence_id}/contacts/import"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.peachdeskai.com/api/v1/sequences/{sequence_id}/contacts/import")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.peachdeskai.com/api/v1/sequences/{sequence_id}/contacts/import")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"import_id": 123,
"status": "<string>",
"started_at": "2023-11-07T05:31:56Z",
"completed_at": "2023-11-07T05:31:56Z",
"source_type": "<string>",
"rows_read": 123,
"rows_accepted": 123,
"rows_rejected": 123,
"failure_reason": "<string>",
"rejections_by_reason": {},
"rejections": [
{
"import_id": 123,
"row_number": 123,
"reason_code": "<string>",
"rejected_value": "<string>"
}
],
"totals": {
"imports": 0,
"rows_read": 0,
"accepted": 0,
"rejected": 0
},
"totals_rejections_by_reason": {},
"imports": [
{
"id": 123,
"status": "<string>",
"completed_at": "2023-11-07T05:31:56Z",
"rows_read": 123,
"rows_accepted": 123,
"rows_rejected": 123,
"failure_reason": "<string>"
}
]
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Authorizations
Interactive user session: the login JWT, sent as Authorization: Bearer <token>.
Path Parameters
Response
Successful Response
This sequence's imports: the last one, and all of them.
Both, because they answer different questions and the second one was
missing. The LATEST fields drive the rejection tile, which is specified to
VANISH when nothing was rejected тАФ an aggregate is never empty again after
one bad upload, so a tile fed from totals could never go away. The
CUMULATIVE fields answer the question an operator actually asks: three
files went up, 2,500 of 3,000 rows enrolled, where are the other 500.
Nothing about the newest import contains that answer.
The vanishing rule survives on the cumulative side too, and the condition
is totals.rejected > 0 тАФ NOT totals_rejections_by_reason being
non-empty. The two agree only while every rejection carries a reason code
the client renders, and they diverge exactly when it matters: a client
deliberately strips codes that are not ingest rejections (do_not_call
and friends тАФ dial-time suppression is not a refused row), so gating on
the map hides the card and tells an operator nothing happened when 500
rows did not make it. Incomplete beats wrong; show "N rows didn't make it"
with no reason tiles. The divergence is deliberate тАФ do not reconcile it
by changing the client to match the tidier-looking rule.
import_id null means this sequence has never been imported, and then
totals.imports is 0. A client must render nothing rather than a card of
zeros: an import that has not happened is not an import that rejected
nobody.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Every import of this sequence, added up.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes
Show child attributes

