Quickstart: Find People Showing Intent on a Topic
What this does
Start from a topic, get back the people researching it right now, strongest intent first. This is the list-building direction: the enrichment quickstart starts from people you already have, this one finds people you do not.
topic in -> free preview -> dry_run cost -> POST /api/v1/intent/people (paged) -> people out
Each row is one person, returned as a hem (sha256 of a normalized email) you can match against your own contacts, plus a person_id. Raw emails are never returned unless you ask for them with resolve.
Before you start
You need an organization API key + secret pair; the Authentication guide walks through it. Every request below sends both headers:
X-Api-Key: dlvr_...
X-Api-Secret: ...
1. Find the topic_id
Topics are identified by topic_id. Search the taxonomy by name:
curl "https://api.delivr.ai/api/v1/taxonomy/topics?search=crm&limit=5" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "X-Api-Secret: YOUR_API_SECRET"{
"response": {
"topics": [
{
"topic_id": "4eyes_103456",
"name": "CRM Software",
"status": "active",
"topic_type": "B2B"
}
]
}
}Copy the topic_id of the topic you want. The Taxonomy API guide covers browsing by category and requesting a topic that does not exist yet.
2. Preview for free
POST /api/v1/intent/people/preview returns a capped sample (up to 25) of the strongest people on the topic, plus the topic's total count. Nothing is billed.
curl -X POST "https://api.delivr.ai/api/v1/intent/people/preview" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "X-Api-Secret: YOUR_API_SECRET" \
-H "Content-Type: application/json" \
-d '{"topic_id": "4eyes_103456", "min_score": "high"}'{
"response": {
"topic_id": "4eyes_103456",
"preview": true,
"count": 316075,
"results": [
{
"hem": "7bb9e30283184c3b4bbbf2262a600be7165d7e6f50e424a611aa64394e7ecdb5",
"score": "high",
"perc_score": 97
}
]
},
"as_of": "2026-06-21"
}- The preview does not paginate: it takes no
cursorand returns nonext_cursor. You always get the top of the list. countis the topic's full people total, so the sample is only a window onto it.- Preview rows carry no
person_idand never aseen_email.resolve: trueadds amasked_email(for examplej***@acme.com) so you can recognize people without paying for them. as_ofis the single day the intent data covers. The dataset is rebuilt daily, so a person can be on a topic one day and not the next.
3. Check the cost with dry_run
The paid endpoint bills one record per person returned. Send the same request you plan to run with "dry_run": true to see what it would charge, without being charged and without getting records back:
curl -X POST "https://api.delivr.ai/api/v1/intent/people" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "X-Api-Secret: YOUR_API_SECRET" \
-H "Content-Type: application/json" \
-d '{"topic_id": "4eyes_103456", "min_score": "high", "page_size": 50, "dry_run": true}'{
"dry_run": true,
"meter": "intent_signal_scored",
"records_to_charge": 50,
"note": "Cost preview only: no results were returned and nothing was billed. A live run of this request would charge records_to_charge against the named meter."
}records_to_charge covers that one request, which is one page. To estimate a full pull, use the preview's count. Details in Rate Limits and Metering.
4. Pull the list with cursor paging
Drop dry_run and page through the results. Results are ordered by perc_score, strongest first. page_size is 1 to 500 (default 50).
curl -X POST "https://api.delivr.ai/api/v1/intent/people" \
-H "X-Api-Key: YOUR_API_KEY" \
-H "X-Api-Secret: YOUR_API_SECRET" \
-H "Content-Type: application/json" \
-d '{"topic_id": "4eyes_103456", "min_score": "high", "page_size": 50}'{
"response": {
"topic_id": "4eyes_103456",
"count": 316075,
"results": [
{
"person_id": "c41f6a0d92b7e5381a4d7f0e63b9a2c58d1e9f47b30a6c25e8d7149fa3b06e21",
"hem": "7bb9e30283184c3b4bbbf2262a600be7165d7e6f50e424a611aa64394e7ecdb5",
"score": "high",
"perc_score": 97
}
],
"next_cursor": "eyJ0IjoiNGV5ZXNfMTAzNDU2Iiwic2siOiIwMiM3YmI5ZTMwMiJ9"
},
"as_of": "2026-06-21"
}To get the next page, send the same body with "cursor" set to the next_cursor you received. Stop only when next_cursor is absent:
- A page can come back shorter than
page_size, or empty, because people who opted out are removed after the page is read. That is not the end of the results. countis returned on the first page only.resolve: trueaddsseen_emailwhere we have it, andresolve_linkedin: trueaddslinkedin_url. Both are billed at the same intent rate.
Complete example: pull a topic (Python)
import requests
API = "https://api.delivr.ai/api/v1/intent/people"
HEADERS = {
"X-Api-Key": "YOUR_API_KEY",
"X-Api-Secret": "YOUR_API_SECRET",
}
body = {"topic_id": "4eyes_103456", "min_score": "high", "page_size": 500}
people = []
while True:
resp = requests.post(API, headers=HEADERS, json=body, timeout=60)
resp.raise_for_status()
page = resp.json()["response"]
people.extend(page["results"])
cursor = page.get("next_cursor")
if not cursor:
break
body["cursor"] = cursor
print(f"pulled {len(people)} people")Errors you might see
| Status | Meaning | Fix |
|---|---|---|
400 | Malformed request (for example, missing topic_id) | Check the request body against the examples above |
401 | Missing or invalid key/secret pair | Re-copy both halves from the dashboard; see Authentication |
429 with error platform_cap_exceeded | Over a daily or monthly usage limit | Do not retry straight away: kind says whether to wait for resets_at, send a smaller request, or contact support; see Rate Limits and Metering |
Any other 429 | Over your request rate limit | Back off and retry; see Rate Limits and Metering |
Where to go next
- Several topics at once:
POST /api/v1/intent/people/multitakes a list of topics, and companies instead of people:POST /api/v1/intent/companiestakes the same flow at the account level. Both have/previewvariants. - Restrict to your own audience: pass
audience_idto get only the members of one of your audiences who show intent on the topic. See the endpoint reference. - Which API should I use? if your use case is not list building.
Updated about 3 hours ago
