curl --request GET \
--url https://api.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/timeline \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/timeline"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/timeline', 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.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/timeline",
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.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/timeline"
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.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/timeline")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/timeline")
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{
"canonical_lead_id": "<string>",
"context_columns": [
"<string>"
],
"dataset_id": "<string>",
"dataset_slug": "<string>",
"details": [
{
"definition": "<string>",
"earlier": [
{
"observed_at": "2023-11-07T05:31:56Z",
"quote": "<string>",
"source_kind": "<string>",
"source_ref": "<string>",
"value": "<string>"
}
],
"key": "<string>",
"label": "<string>",
"observed_at": "2023-11-07T05:31:56Z",
"quote": "<string>",
"source_kind": "<string>",
"source_ref": "<string>",
"value": "<string>"
}
],
"emails": [
"<string>"
],
"entries": [
{
"answered_call": true,
"at": "2023-11-07T05:31:56Z",
"detail": "<string>",
"direction": "<string>",
"from_playbook": true,
"kind": "<string>",
"meeting_at": "2023-11-07T05:31:56Z",
"ref": "<string>",
"status": "<string>",
"summary": "<string>"
}
],
"lead_reference": "<string>",
"phones": [
"<string>"
],
"reset_at": "2023-11-07T05:31:56Z",
"row": {},
"timing": {
"awaiting_our_reply": true,
"captured_at": "2023-11-07T05:31:56Z",
"days_since_capture": 123,
"days_since_last_outbound": 123,
"days_since_last_response": 123,
"last_meeting_at": "2023-11-07T05:31:56Z",
"last_outbound_at": "2023-11-07T05:31:56Z",
"last_outbound_by_channel": {},
"last_response_at": "2023-11-07T05:31:56Z",
"lead_zone": {
"evidence": "<string>",
"source": "<string>",
"timezone": "<string>"
},
"local_time": "<string>",
"next_meeting_at": "2023-11-07T05:31:56Z",
"next_working_window_start": "2023-11-07T05:31:56Z",
"now": "2023-11-07T05:31:56Z",
"outbound_messages": 123,
"phone_hours": {
"local_time": "<string>",
"next_working_window_start": "2023-11-07T05:31:56Z",
"timezone": "<string>",
"within_working_hours": true
},
"reachability": "<string>",
"reached_at": "2023-11-07T05:31:56Z",
"reached_via": "<string>",
"timezone": "<string>",
"unanswered_outbound_in_a_row": 123,
"within_working_hours": true
},
"unavailable": {},
"undeliverable_emails": {}
}{
"code": "not_found",
"details": {},
"message": "<string>"
}GetLeadTimelineAPI mirrors the erdo_get_lead_timeline MCP tool.
curl --request GET \
--url https://api.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/timeline \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/timeline"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/timeline', 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.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/timeline",
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.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/timeline"
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.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/timeline")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.erdo.ai/v1/datasets/{datasetSlug}/leads/{leadRef}/timeline")
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{
"canonical_lead_id": "<string>",
"context_columns": [
"<string>"
],
"dataset_id": "<string>",
"dataset_slug": "<string>",
"details": [
{
"definition": "<string>",
"earlier": [
{
"observed_at": "2023-11-07T05:31:56Z",
"quote": "<string>",
"source_kind": "<string>",
"source_ref": "<string>",
"value": "<string>"
}
],
"key": "<string>",
"label": "<string>",
"observed_at": "2023-11-07T05:31:56Z",
"quote": "<string>",
"source_kind": "<string>",
"source_ref": "<string>",
"value": "<string>"
}
],
"emails": [
"<string>"
],
"entries": [
{
"answered_call": true,
"at": "2023-11-07T05:31:56Z",
"detail": "<string>",
"direction": "<string>",
"from_playbook": true,
"kind": "<string>",
"meeting_at": "2023-11-07T05:31:56Z",
"ref": "<string>",
"status": "<string>",
"summary": "<string>"
}
],
"lead_reference": "<string>",
"phones": [
"<string>"
],
"reset_at": "2023-11-07T05:31:56Z",
"row": {},
"timing": {
"awaiting_our_reply": true,
"captured_at": "2023-11-07T05:31:56Z",
"days_since_capture": 123,
"days_since_last_outbound": 123,
"days_since_last_response": 123,
"last_meeting_at": "2023-11-07T05:31:56Z",
"last_outbound_at": "2023-11-07T05:31:56Z",
"last_outbound_by_channel": {},
"last_response_at": "2023-11-07T05:31:56Z",
"lead_zone": {
"evidence": "<string>",
"source": "<string>",
"timezone": "<string>"
},
"local_time": "<string>",
"next_meeting_at": "2023-11-07T05:31:56Z",
"next_working_window_start": "2023-11-07T05:31:56Z",
"now": "2023-11-07T05:31:56Z",
"outbound_messages": 123,
"phone_hours": {
"local_time": "<string>",
"next_working_window_start": "2023-11-07T05:31:56Z",
"timezone": "<string>",
"within_working_hours": true
},
"reachability": "<string>",
"reached_at": "2023-11-07T05:31:56Z",
"reached_via": "<string>",
"timezone": "<string>",
"unanswered_outbound_in_a_row": 123,
"within_working_hours": true
},
"unavailable": {},
"undeliverable_emails": {}
}{
"code": "not_found",
"details": {},
"message": "<string>"
}Authorizations
An Erdo API key (erdo_api_...) or scoped token (erdo_token_...).
Response
Success response
None of these columns is something the lead said: each is marked by the dataset's contract as bookkeeping, attribution, or a column the platform stamps itself, under whatever name the contract gave it. Read through partition, never directly.
conversation, one entry per question with the answers it replaced.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
row's arrival and the answers above begin there, because that is what the engine decides from; absent for a lead that was never reset.
Show child attributes
Show child attributes
the platform so "no response four days after the second email" is matched on numbers rather than on date arithmetic the model does.
Show child attributes
Show child attributes
listed here is unknown, never empty — the evaluation is told so.
Show child attributes
Show child attributes
showed cannot take mail — it bounced, or the person reported it as spam — with what the provider said. Email to one of them is refused (channelRefusal): a second message to a dead mailbox reaches nobody and costs the development's sending reputation, and one to a person who reported us is mail they have already refused.
Show child attributes
Show child attributes

