API Reference

People

The people at your activated accounts: rosters, decision-maker search, verified emails, phones, lists, and CRM push. Data is unlimited on every plan, so none of these endpoints draw down a credit balance.

People come from two places. When you activate an account, Hunch loads its full employee roster automatically (source employee). When you run a Find People search, matched decision makers are saved with their match tier (source waterfall). Both land in the same collection and dedupe by LinkedIn profile per account.

List people

GET/people

Returns people newest first, paginated. Supports filters:

Query parameters
account_idstringoptional

Only people at this account.

job_levelstringoptional

C-Team, VP, Director, Manager, or Staff.

country_codestringoptional

ISO 2-letter country code, e.g. US.

sourcestringoptional

employee (roster sync) or waterfall (Find People match).

has_emailbooleanoptional

true for only people with a verified email; false for people without one.

list_idstringoptional

Only people saved to this list.

owner_idstringoptional

Only people assigned to this team member (user id).

searchstringoptional

Substring match on name, title, or headline.

sortstringoptional

created_at (default) or full_name.

orderstringoptional

asc or desc. Default desc.

pageintegeroptional

Page number. Default 1.

per_pageintegeroptional

Max 100. Default 50.

Request
curl "https://usehunch.co/api/v1/people?job_level=VP&has_email=true&per_page=25" \
  -H "Authorization: Bearer YOUR_API_KEY"
Response
{
  "data": [
    {
      "id": "...",
      "account_id": "...",
      "full_name": "Lena Tran",
      "title": "Head of Revenue Operations",
      "headline": "RevOps at Fielder",
      "linkedin_url": "https://www.linkedin.com/in/lenatran",
      "email": "lena@fielder.app",
      "email_checked_at": "2026-07-06T...",
      "phone": null,
      "phone_checked_at": null,
      "location": "Denver, US",
      "country_code": "US",
      "connections_count": 500,
      "profile_picture_url": "...",
      "job_level": "Director",
      "source": "waterfall",
      "icp_tier": 2,
      "ranking": 1,
      "owner_id": null,
      "created_at": "2026-07-06T..."
    }
  ],
  "pagination": { "total": 128, "page": 1, "per_page": 25, "has_more": true }
}

Get a person

GET/people/:id

Returns the full person record plus list_ids, the ids of every list they are saved to.

Find people

POST/people/find

Describe who you want in plain English. Hunch compiles it into a prioritized title cascade (the ideal role first, adjacent roles behind it, a sensible fallback last), runs it at each activated account, and attaches a verified work email to every hit. Matches are saved to People and returned in the response.

Body fields
querystringrequired

Who you want, in plain English. e.g. "The demand generation leader. If none, whoever runs marketing. Skip agencies and consultants."

account_idsstring[]optional

Specific activated accounts to search. Defaults to the most recent activated accounts.

max_accountsintegeroptional

How many accounts one call sweeps. Default 20, max 50. For bigger rosters, call again with account_ids batches.

Request
curl -X POST https://usehunch.co/api/v1/people/find \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "query": "VP of Sales or CRO in the US. If neither, whoever runs revenue operations.",
    "account_ids": ["acc_123"]
  }'
Response
{
  "data": {
    "found": 3,
    "accountsSearched": 1,
    "tiers": 3,
    "cascade": [ ... ],
    "contacts": [ { "id": "...", "full_name": "...", "email": "...", "icp_tier": 1, ... } ]
  }
}

icp_tier on each match tells you which tier matched: 1 is the ideal role, higher numbers are fallbacks. Searches can take a minute or two for many accounts since lookups are paced for reliability.

Load an account's roster

POST/people/sync

Loads (or refreshes) the full employee roster for an activated account into People. This runs automatically when an account is activated, so you only need it for accounts activated before rosters existed or to refresh one.

Body fields
account_idstringrequired

An ACTIVE account id.

Response
{ "data": { "account_id": "...", "synced": 43 } }

Reveal a work email

POST/people/:id/email

Returns the verified work email for a person and stores it on the record. Idempotent: if the email is already known it is returned without a new lookup. email is null when no verified address exists.

Response
{ "data": { "id": "...", "email": "lena@fielder.app" } }

Reveal a phone number

POST/people/:id/phone

Returns a mobile or direct phone for a person and stores it. Coverage is focused on the US;phone is null when none is found.

Assign an owner

PUT/people/:id/owner

Assigns a person to a team member, the same way accounts are assigned. owner_id must be a workspace member's user id (see GET /members), or null to unassign. Members with scoped visibility see the people at their accounts plus anyone assigned to them directly.

Body fields
owner_idstring | nulloptional

A member's user id, or null to unassign.

Response
{ "data": { "id": "...", "owner_id": "..." } }

Push people to your CRM

POST/people/crm-push

Pushes people to the connected CRMs as Contacts. Each person's company record is created or updated first (with its signal context), so contacts always land linked to an account. Every selected person is pushed with whatever their row holds. Deduping is a waterfall: verified email first, then LinkedIn URL via a Hunch-managed CRM field (created automatically) - so re-pushing the same person updates their record instead of duplicating it, even when no email exists yet.

Body fields
contact_idsstring[]required

Person ids to push. Any size - pushes over 100 run in the background and return a run_id to poll via GET /push-runs/:id.

providerstringoptional

hubspot or salesforce. Omit to push to every connected CRM.

Response
{
  "data": {
    "pushed": 4,
    "failed": 0,
    "skippedNoEmail": 0,
    "providers": ["hubspot"],
    "results": [ { "contactId": "...", "provider": "hubspot", "ok": true, "created": true } ]
  }
}

People lists

GET/people/lists

Lists every saved people list with member counts.

POST/people/lists
Body fields
namestringrequired

List name, e.g. "Q3 outreach - RevOps leaders". Creating an existing name returns that list.

DELETE/people/lists/:id

Deletes a list. The people in it are kept.

POST/people/lists/:id/members
Body fields
addstring[]optional

Person ids to add (max 500 per call).

removestring[]optional

Person ids to remove (max 500 per call).

Response
{ "data": { "list_id": "...", "added": 12, "removed": 0 } }

Enrich an account

POST/accounts/:id/enrich

Runs enrichment for an ACTIVE account on demand: full company profile, workforce breakdown by department and country, and the employee roster into People. This is the same pipeline that runs automatically on activation, so you only need it to refresh or backfill. Returns the updated account.