API reference
List activity
The log, newest first: what you and mySDR recorded (emails with their step, template and thread, replies, bounces, meetings, out-of-office, unsubscribes, referrals, notes with their source, status changes). For one person (lead), one company and its people (company), one address (email), or the whole organization; the whole organization includes your work log (notes about nobody). Start a new session with it to see where you left off. Lines with the same time come in the order they were logged, latest first. Page with before = next_before: nothing is skipped, also when many lines share one date. The user sees the same log on the Activity tab.
Authentication
Send Authorization: Bearer gtk_…. Create the key under Connect assistant → API keys. Every gtk_ key can call these routes, also while the Signals API is closed. A missing, invalid or revoked key is 401.
Query parameters
leadstring— A person: a row id, a LinkedIn URL or their address.companystring— A company: a row id, its domain, page or name. Includes its people in the Leads table and its general addresses.emailstring— One address.campaignstring— Only this campaign.typestring— Only these types, separated by commas (the types of POST /outreach/activity, plusstatus_changed,stage_changedandowner_changed, which mySDR writes itself, andsignal_hit: a hit of one of your own signals, with the signal indetail).actionstring— Only these actions of your own (call,linkedin_message), separated by commas, up to 20.with_textboolean—trueaddstextto every line: the email you logged with it (null for a line without one). Defaultfalse, so a long list stays short; ask for it to read back what you sent before a follow-up.sincestring— Only from this ISO time, or from the start of this date (Brussels time).beforestring—next_beforeof the previous page, or an ISO time or a date: only what is older (a date means before that day starts).limitinteger— From 1 to 200. Defaults to 50.
Response
objectstring· required — Alwayslist. One of:list.rowobject— Withleadorcompany: the row (id,object,name).dataobject[]· required — Log lines:id,at,type,label(for an action of your own, its label),action(your own action, or null),subject,summary,email,step,template,thread_id,sentiment,until,detail,source_url,campaign_id,row(null for a work log line) andvia(the name of the key that logged it; null from the app); withwith_text=truealsotext.next_beforestring | null· required — An opaque cursor: pass it asbeforefor the next page; null at the end.dashboard_urlstring· required — The table in mySDR; for the whole organization or an address, the Activity tab.
Credits
Free. This call never uses credits.
Errors
- 400
invalid_request— More than one oflead,companyandemail, an unknowntype, anactionthat is not a key (or is a type), a date that is not valid, or alimitoutside 1 to 200. - 404
not_found— No person or company matches. - 401
authentication_error— The Authorization header is missing, or the key is unknown or revoked. - 403
permission_error— API access is not part of your plan, or your account is suspended. - 429
rate_limit_error— More than 60 requests per minute, or more than 3 at the same time, on one key. Wait for the Retry-After header. - 503
service_unavailable— The API is temporarily unavailable. Retry later. - 500
internal_error— Something went wrong on our side.
Example
cURL
curl "https://mysdr.app/api/v1/outreach/activity?company=acme-logistics.example" \
-H "Authorization: Bearer $MYSDR_API_KEY"
JavaScript
const response = await fetch('https://mysdr.app/api/v1/outreach/activity?company=acme-logistics.example', {
method: 'GET',
headers: {
Authorization: `Bearer ${process.env.MYSDR_API_KEY}`
}
});
const body = await response.json();
Python
import json
import os
import urllib.request
request = urllib.request.Request(
"https://mysdr.app/api/v1/outreach/activity?company=acme-logistics.example",
headers={
"Authorization": f"Bearer {os.environ['MYSDR_API_KEY']}"
},
method="GET",
)
with urllib.request.urlopen(request) as response:
body = json.load(response)
Example response
{
"object": "list",
"row": {
"id": "sav_2b9e8d10-7f4a-4a51-8c2e-5d1f0a3b6c77",
"object": "company",
"name": "Acme Logistics"
},
"data": [
{
"id": "a71c…",
"at": "2026-10-22T08:31:00.000Z",
"type": "email_sent",
"label": "Email sent",
"action": null,
"subject": "Your open roles",
"summary": null,
"email": "jobs@acme-logistics.example",
"step": 1,
"template": "step1_jobs_inbox",
"thread_id": "thread-88",
"sentiment": null,
"until": null,
"detail": null,
"source_url": null,
"campaign_id": null,
"row": {
"id": "sav_2b9e8d10-7f4a-4a51-8c2e-5d1f0a3b6c77",
"object": "company",
"name": "Acme Logistics"
},
"via": "Grok Bot"
},
{
"id": "9c4d…",
"at": "2026-10-21T14:02:00.000Z",
"type": "note",
"label": "Call",
"action": "call",
"subject": "Spoke to the HR manager",
"summary": "Call back after the holidays.",
"email": null,
"step": null,
"template": null,
"thread_id": null,
"sentiment": null,
"until": null,
"detail": {
"action": "call",
"action_label": "Call"
},
"source_url": null,
"campaign_id": null,
"row": {
"id": "sav_2b9e8d10-7f4a-4a51-8c2e-5d1f0a3b6c77",
"object": "company",
"name": "Acme Logistics"
},
"via": "Grok Bot"
},
{
"id": "5e0b…",
"at": "2026-10-19T15:07:04.000Z",
"type": "note",
"label": "Note",
"action": null,
"subject": "Open roles counted",
"summary": "15 white-collar roles; 2 internships not counted.",
"email": null,
"step": null,
"template": null,
"thread_id": null,
"sentiment": null,
"until": null,
"detail": null,
"source_url": "https://acme-logistics.example/jobs",
"campaign_id": null,
"row": {
"id": "sav_2b9e8d10-7f4a-4a51-8c2e-5d1f0a3b6c77",
"object": "company",
"name": "Acme Logistics"
},
"via": "Grok Bot"
}
],
"next_before": null,
"dashboard_url": "https://mysdr.app/en/gtm/companies"
}