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 cursor and returns no next_cursor. You always get the top of the list.
  • count is the topic's full people total, so the sample is only a window onto it.
  • Preview rows carry no person_id and never a seen_email. resolve: true adds a masked_email (for example j***@acme.com) so you can recognize people without paying for them.
  • as_of is 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.
  • count is returned on the first page only.
  • resolve: true adds seen_email where we have it, and resolve_linkedin: true adds linkedin_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

StatusMeaningFix
400Malformed request (for example, missing topic_id)Check the request body against the examples above
401Missing or invalid key/secret pairRe-copy both halves from the dashboard; see Authentication
429 with error platform_cap_exceededOver a daily or monthly usage limitDo 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 429Over your request rate limitBack off and retry; see Rate Limits and Metering

Where to go next

  • Several topics at once: POST /api/v1/intent/people/multi takes a list of topics, and companies instead of people: POST /api/v1/intent/companies takes the same flow at the account level. Both have /preview variants.
  • Restrict to your own audience: pass audience_id to 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.

Did this page help you?