curl --request GET \
--url https://api.lemlist.com/api/v2/crm/logs \
--header 'Authorization: Basic <encoded-value>'import requests
url = "https://api.lemlist.com/api/v2/crm/logs"
headers = {"Authorization": "Basic <encoded-value>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Basic <encoded-value>'}};
fetch('https://api.lemlist.com/api/v2/crm/logs', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));require 'uri'
require 'net/http'
url = URI("https://api.lemlist.com/api/v2/crm/logs")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Basic <encoded-value>'
response = http.request(request)
puts response.read_body<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.lemlist.com/api/v2/crm/logs",
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: Basic <encoded-value>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}Get CRM Logs
Retrieves the CRM sync history of your team, a contact or a company.
curl --request GET \
--url https://api.lemlist.com/api/v2/crm/logs \
--header 'Authorization: Basic <encoded-value>'import requests
url = "https://api.lemlist.com/api/v2/crm/logs"
headers = {"Authorization": "Basic <encoded-value>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Basic <encoded-value>'}};
fetch('https://api.lemlist.com/api/v2/crm/logs', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));require 'uri'
require 'net/http'
url = URI("https://api.lemlist.com/api/v2/crm/logs")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Basic <encoded-value>'
response = http.request(request)
puts response.read_body<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.lemlist.com/api/v2/crm/logs",
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: Basic <encoded-value>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}Authorizations
Basic authentication header of the form Basic <encoded-value>, where <encoded-value> is the base64-encoded string username:password.
Query Parameters
The contact whose history to read (ctc_xxx). Pass contactId or companyId, not both; without either, the team's history is listed. An empty value answers INVALID_PARAMETER.
^ctc_[a-zA-Z0-9]+$The company whose history to read (cpn_xxx). Pass contactId or companyId, not both; without either, the team's history is listed. An empty value answers INVALID_PARAMETER.
^cpn_[a-zA-Z0-9]+$Page number, starting at 1. Default: 1. page × limit must not exceed 5,000 (PAGE_OUT_OF_RANGE): beyond the 5,000 most recent rows, call again with to set to the createdAt of the last log you received. to is inclusive, so the logs of that instant come back: skip the _ids you already have.
x >= 1Number of logs per page, from 1 to 100. Default: 100.
1 <= x <= 100Only the logs in these states, comma-separated: pending, done, error, aborted. When the parameter is repeated, the last value is used.
Only the logs of these categories, comma-separated: contact, company, association, activity, email, linkedin, sms, whatsapp, call, note, task, deal, event.
Only the logs of these operations, comma-separated, by their method name (see CrmLog.method). A name covers both directions: contact_update is a lemlist write and a change received from the CRM. With category, both filters apply. When the parameter is repeated, the last value is used.
Only the logs created at or after this date (ISO 8601, read in UTC: a time without offset is UTC, a date without time starts at 00:00). For a record, no default: its whole history. For the team, 31 days before to by default, and from and to may span 31 days at most (INVALID_DATE_RANGE): with dates without time, from=2026-08-01&to=2026-08-31 is the widest window.
Only the logs created at or before this date (ISO 8601, read in UTC: a time without offset is UTC, a date without time covers that whole day, up to 23:59:59.999). Default: now.
Response
Success
Show child attributes
Show child attributes
Whether older logs exist past this page. For a contact or a company, it stays false on the page ending at row 5,000, even when older logs exist. For the team, it says whether they exist, and the next page answers PAGE_OUT_OF_RANGE. Past row 5,000, call again with to.
Was this page helpful?