Prospects API
Read your prospects: their status, tags, and verification, and, with an extra permission, their names and contact details.
Requires the prospects permission. Personal data also requires prospects:pii. See Personal data.
| Endpoint | Returns |
|---|---|
GET /api/v1/prospects |
A paginated list of prospects |
GET /api/v1/prospects/:id |
One prospect |
List prospects
GET https://integrations.stokedhq.com/api/v1/prospects
With no filters, the list contains every prospect in your community: pending, active, and inactive, including prospects whose personal data has been erased. See Erased prospects.
Parameters
| Parameter | Description |
|---|---|
filter[status] |
One or more of pending, active, inactive, separated by commas: filter[status]=pending,active |
filter[created_since] |
Only prospects created at or after this time |
filter[updated_since] |
Only prospects updated at or after this time. Use this for incremental syncing. |
page[number] |
The page to return. Defaults to 1. |
page[size] |
Prospects per page. Defaults to 50, maximum 200. |
Time filters accept an ISO 8601 timestamp with a time zone (2026-09-01T00:00:00Z) or a date (2026-09-01, read as midnight UTC). Both are inclusive.
Any other parameter — including sort — returns a 400 error. Prospects always come back least recently updated first.
Request
cURL
curl -G "https://integrations.stokedhq.com/api/v1/prospects" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/vnd.api+json" \
--data-urlencode "filter[updated_since]=2026-09-01T00:00:00Z"
Ruby
require "net/http"
require "json"
uri = URI("https://integrations.stokedhq.com/api/v1/prospects")
uri.query = URI.encode_www_form("filter[updated_since]" => "2026-09-01T00:00:00Z")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer YOUR_API_KEY"
request["Accept"] = "application/vnd.api+json"
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }
raise "HTTP #{response.code}: #{response.body}" unless response.is_a?(Net::HTTPSuccess)
puts JSON.parse(response.body)["data"]
Python
import requests
response = requests.get(
"https://integrations.stokedhq.com/api/v1/prospects",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Accept": "application/vnd.api+json",
},
params={"filter[updated_since]": "2026-09-01T00:00:00Z"},
)
response.raise_for_status()
print(response.json()["data"])
C#
using System.Net.Http.Headers;
using System.Text.Json;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "YOUR_API_KEY");
client.DefaultRequestHeaders.Accept.ParseAdd("application/vnd.api+json");
using var response = await client.GetAsync("https://integrations.stokedhq.com/api/v1/prospects?filter[updated_since]=2026-09-01T00:00:00Z");
response.EnsureSuccessStatusCode();
using var document = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
Console.WriteLine(document.RootElement.GetProperty("data"));
JavaScript
const url = new URL("https://integrations.stokedhq.com/api/v1/prospects");
url.searchParams.set("filter[updated_since]", "2026-09-01T00:00:00Z");
const response = await fetch(url, {
headers: {
Authorization: "Bearer YOUR_API_KEY",
Accept: "application/vnd.api+json",
},
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
const { data } = await response.json();
console.log(data);
Response
This key has both prospects and prospects:pii.
{
"data": [
{
"type": "prospects",
"id": "01k5examplepr0spect0000001",
"attributes": {
"first_name": "Mike",
"last_name": "Sample",
"email": "mike@example.com",
"phone_number": "+12025550101",
"status": "active",
"tags": [
"school-run"
],
"phone_verified": true,
"email_verified": false,
"conversations_count": 1,
"created_at": "2026-08-20T14:00:00Z",
"updated_at": "2026-09-01T15:00:00Z"
},
"relationships": {
"conversations": {
"links": {
"related": "https://integrations.stokedhq.com/api/v1/conversations?filter%5Bprospect%5D=01k5examplepr0spect0000001"
}
}
},
"links": {
"self": "https://integrations.stokedhq.com/api/v1/prospects/01k5examplepr0spect0000001"
},
"meta": {
"pii": true
}
}
],
"links": {
"self": "https://integrations.stokedhq.com/api/v1/prospects?filter%5Bupdated_since%5D=2026-09-01T00%3A00%3A00Z&page%5Bnumber%5D=1&page%5Bsize%5D=50",
"first": "https://integrations.stokedhq.com/api/v1/prospects?filter%5Bupdated_since%5D=2026-09-01T00%3A00%3A00Z&page%5Bnumber%5D=1&page%5Bsize%5D=50",
"prev": null,
"next": null,
"last": "https://integrations.stokedhq.com/api/v1/prospects?filter%5Bupdated_since%5D=2026-09-01T00%3A00%3A00Z&page%5Bnumber%5D=1&page%5Bsize%5D=50"
},
"meta": {
"page": 1,
"per_page": 50,
"total_count": 1,
"total_pages": 1
}
}
Get a prospect
GET https://integrations.stokedhq.com/api/v1/prospects/:id
Returns the same record as the list. An ID that doesn’t exist in your community returns 404.
The id is the same value a conversation gives you in relationships.prospect, and that relationship’s links.related is this URL.
Request
cURL
curl "https://integrations.stokedhq.com/api/v1/prospects/01k5examplepr0spect0000001" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Accept: application/vnd.api+json"
Ruby
require "net/http"
require "json"
uri = URI("https://integrations.stokedhq.com/api/v1/prospects/01k5examplepr0spect0000001")
request = Net::HTTP::Get.new(uri)
request["Authorization"] = "Bearer YOUR_API_KEY"
request["Accept"] = "application/vnd.api+json"
response = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(request) }
raise "HTTP #{response.code}: #{response.body}" unless response.is_a?(Net::HTTPSuccess)
puts JSON.parse(response.body)["data"]
Python
import requests
response = requests.get(
"https://integrations.stokedhq.com/api/v1/prospects/01k5examplepr0spect0000001",
headers={
"Authorization": "Bearer YOUR_API_KEY",
"Accept": "application/vnd.api+json",
},
)
response.raise_for_status()
print(response.json()["data"])
C#
using System.Net.Http.Headers;
using System.Text.Json;
using var client = new HttpClient();
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", "YOUR_API_KEY");
client.DefaultRequestHeaders.Accept.ParseAdd("application/vnd.api+json");
using var response = await client.GetAsync("https://integrations.stokedhq.com/api/v1/prospects/01k5examplepr0spect0000001");
response.EnsureSuccessStatusCode();
using var document = JsonDocument.Parse(await response.Content.ReadAsStringAsync());
Console.WriteLine(document.RootElement.GetProperty("data"));
JavaScript
const url = new URL("https://integrations.stokedhq.com/api/v1/prospects/01k5examplepr0spect0000001");
const response = await fetch(url, {
headers: {
Authorization: "Bearer YOUR_API_KEY",
Accept: "application/vnd.api+json",
},
});
if (!response.ok) throw new Error(`HTTP ${response.status}: ${await response.text()}`);
const { data } = await response.json();
console.log(data);
Response
{
"data": {
"type": "prospects",
"id": "01k5examplepr0spect0000001",
"attributes": {
"first_name": "Mike",
"last_name": "Sample",
"email": "mike@example.com",
"phone_number": "+12025550101",
"status": "active",
"tags": [
"school-run"
],
"phone_verified": true,
"email_verified": false,
"conversations_count": 1,
"created_at": "2026-08-20T14:00:00Z",
"updated_at": "2026-09-01T15:00:00Z"
},
"relationships": {
"conversations": {
"links": {
"related": "https://integrations.stokedhq.com/api/v1/conversations?filter%5Bprospect%5D=01k5examplepr0spect0000001"
}
}
},
"links": {
"self": "https://integrations.stokedhq.com/api/v1/prospects/01k5examplepr0spect0000001"
},
"meta": {
"pii": true
}
}
}
Personal data
Attributes marked prospects:pii below are only returned to a key that has the prospects:pii permission as well as prospects.
Without it, those attributes are left out of the response entirely rather than set to null, so null always means “no value” and never “not permitted”. Each record’s meta.pii tells you which kind of response you received.
Prospect attributes
Records with "type": "prospects".
| Attribute | Type | Requires | Description |
|---|---|---|---|
first_name |
string or null | prospects:pii |
null until the prospect has given their name |
last_name |
string or null | prospects:pii |
|
email |
string or null | prospects:pii |
|
phone_number |
string or null | prospects:pii |
In E.164 format, for example +12025550101 |
status |
string | pending (hasn’t verified their contact details yet), active, or inactive |
|
tags |
array of strings | Names of the prospect’s tags | |
phone_verified |
boolean | Whether the phone number has been verified | |
email_verified |
boolean | Whether the email address has been verified | |
conversations_count |
integer | Number of conversations the prospect has started | |
created_at |
timestamp | When the prospect first appeared | |
updated_at |
timestamp | When the prospect last changed. See What changes updated_at. |
Stoked doesn’t collect an address, location, or custom fields for prospects.
Relationships
| Relationship | Description |
|---|---|
conversations |
links.related is the conversations list filtered to this prospect (filter[prospect]). Reading it requires the conversations permission. |
What changes updated_at
A prospect’s updated_at moves forward whenever anything in their API record changes:
- Their name, contact details, status, or verification changes
- A tag is added, removed, renamed, or reordered
- They start a conversation
- Their personal data is erased
Erased prospects
When a prospect’s personal data is erased (for example, after a privacy request), their record stays so their conversations still make sense. Their name and contact fields become null and their status becomes inactive.
Erasure moves updated_at, so your next incremental sync receives the redacted record. Apply it to your copy like any other update so the personal data is removed from your systems too.