Nyne.ai API Login
Person APIs

People Search API

Send one JSON object. query, when present, must be a natural-language JSON string - never an Elasticsearch-style object. Put exact fields under custom_filters. For example, send {"query":"People currently working at acme.com","limit":1}, or a filter-only request such as {"custom_filters":{"companies":["acme.com"]},"limit":25}. Do not send {"query":{"company_domain":"acme.com"}}. Submit each page once. A new search returns 202 plus a request_id; a page already cached for that request can return 200 immediately. Poll GET /person/search?request_id=... with the same credentials every two seconds. A processing poll is 202 with data.completed: false; a completed poll is 200 with data.completed: true. Stop on completion or a terminal 4xx/5xx response. Polling is free. Alternatively, supply callback_url for webhook delivery. Use /company/employees for a broad company roster and /person/search when role, title, location, or other person criteria matter.

POST https://api.nyne.ai/person/search API key

Manual credentials take precedence over your account key.

Overview

The People Search API finds matching people from a natural-language query and structured filters, then returns profile candidates you can qualify, enrich, or route into sales and data workflows.

Best for

  • Building filtered people lists
  • Finding prospects by role, company, location, or keywords
  • Starting a workflow before you have a specific identifier

Returns

  • Matched person profiles
  • Profile identifiers for enrichment
  • Pagination signals for larger result sets

Implementation guide

Search inputs

Use the people search API with natural-language criteria plus structured filters such as role, company, location, keywords, and pagination controls.

Result schema

Each result is a candidate person record with enough profile context to qualify the match before you enrich, score, or route it.

Next step

Send matched identifiers into Person Enrichment when you need a complete profile, contact fields, or social context.

Parameters

query string optional
Natural-language JSON string describing who you're looking for (max 1000 chars). It must not be an object, array, or search DSL. Provide a query and/or structured custom_filters - at least one is required unless paginating with cursor or request_id. With no query, the search runs purely on custom_filters.
limit integer optional
Results per page. Default 10; valid values are 1-100. Larger result sets are retrieved by paginating (see Pagination). Values outside the range return HTTP 400.
show_emails boolean optional
Include verified email addresses in each result.
e.g. true
show_phone_numbers boolean optional
Include phone numbers in each result.
e.g. true
require_emails boolean optional
Only return people for whom a verified email could be found.
e.g. true
require_phone_numbers boolean optional
Only return people for whom a phone number could be found.
e.g. true
require_phones_or_emails boolean optional
Only return people with at least one contact method (email or phone).
e.g. true
insights boolean optional
Attach AI-generated relevance insights per result. When present, insights.why_matched contains concise evidence chips showing the criterion, evidence type, confidence, and a safe short matched phrase when available. Most useful when a query is supplied.
e.g. true
profile_scoring boolean optional
Return a query-fit score (integer 1-5) ranking how well each profile matches the query. Most useful when a query is supplied.
e.g. true
custom_filters object optional
Structured filters - locations, titles, companies, universities, degrees, specialization_categories, plus the array filters industries (industry names, lowercase; common taxonomy synonyms accepted, e.g. ["fintech","financial services"]), keywords (free-text terms that must each appear in the profile text/skills/interests; multiple keywords are ANDed), and languages (spoken languages, 2-3 common forms each, e.g. ["spanish","espanol"] or ["chinese","mandarin","中文"]). companies matches current employers and accepts company names, domains such as acme.com, or company profile URLs. Employer-company filters include min_company_employee_count/max_company_employee_count, company_employee_count_scope, min_company_total_funding_raised/max_company_total_funding_raised, company_funding_stages, company_latest_funding_stages, company_investor_names, company_last_funding_after_date/company_last_funding_before_date, company_funding_round_filters, and company_funding_scope. Each company_funding_round_filters item binds its supplied stages, investor_names, min_amount/max_amount, funded_after_date/funded_before_date, and funded_within_days to the same funding event. Supports array filters (any-of), numeric ranges, booleans, and exact-match values.
cursor string optional
Opaque pagination token from a previous response's next_cursor. Submitting it fetches the next page.
offset integer optional
Starting position for offset pagination (0-indexed). Default 0; offset + limit may not exceed 10000.
request_id string optional
ID of an existing search (returned by the first call). Re-send it with a new offset/limit to page through results, or poll for completion with a GET (polling never consumes credits).
callback_url string optional
HTTPS URL to receive a webhook when the async search reaches a terminal state. Process callbacks idempotently by request_id; polling remains available as a recovery path.

Polling for the result

This endpoint is asynchronous. A successful submit returns a request_id while the job runs in the background. Poll the same path with a GET request - same authentication headers - passing the request_id as a query parameter:

Loading your API credentials...

Each poll returns the job's current status; once it is completed the payload carries the result shown under Responses. Polling an unknown or expired request_id returns 404 request_not_found.

Status Meaning
queued · processing · pending The job is still running - keep polling.
completed The job finished; the payload carries the result and completed: true.
failed Terminal - the job could not complete; the error field explains why.

Poll every few seconds at first, backing off for long-running jobs. Polling is free - status checks never burn credits.

Prefer push delivery?
Supply the optional callback_url parameter and the completed payload is POSTed to your endpoint when the job finishes - no polling required. Delivery is retried up to 5 times with exponential backoff (1s, 5s, 15s, 1m, 5m) and a 30-second timeout per attempt; respond with a 2xx status to acknowledge receipt.

Pagination

A completed search returns one page of results plus the cursor and counters you need to walk the rest. Each search request (a POST) that returns results is billed for the results on that page; only polling an in-flight search with a GET + request_id is free. offset + limit may not exceed 10000.

Knowing when to paginate

Every completed response carries these fields - read them to decide whether to fetch another page:

Field What it tells you
has_more true means more results are available beyond this page - fetch the next page. false means you have reached the end; stop.
next_cursor An opaque token for the next page. Present only when has_more is true (omitted on the last page). Pass it back as the cursor parameter - it already encodes the next offset, limit and request_id.
total_estimate Approximate total number of matches for the query. Use it to size a progress bar or decide how many pages to pull; treat it as an estimate, not an exact count.
offset / limit The slice this response represents: results offset through offset + limit - 1.

Fetching the next page

Method How
Cursor (recommended) Take next_cursor from the response and send it as cursor on the next request (no other params needed). Repeat until has_more is false.
request_id + offset Re-send the original request_id with an increasing offset (e.g. offset: 25, then 50, using your chosen limit).
Repeat the query + offset Re-submit the same query (and identical custom_filters) with a higher offset. The service matches it to the existing search session. Prefer cursor or request_id when you have them - they are unambiguous.

Pagination is forward-only and consistent within a search session: results keep their position, so paging never skips or duplicates a person. Each page you request with a POST is charged for the results it returns; checking status with a GET and a request_id is always free, so you can re-read data you have already retrieved without being charged again.

Credit usage

Credits are charged based on the matched configuration. The listed cost is the per-result unit price.

Feature Credits Notes
Person Search 1 base credits per result returned
Smart Ranking +1 per result when profile_scoring: true
Candidate Insights +1 per result when insights: true
Structured Filters +1 per result when custom_filters is non-empty
Email Data +6 per result when show_emails or require_emails is true
Phone Data +6 per result when show_phone_numbers or require_phone_numbers is true
Any Contact Data +6 per result when require_phones_or_emails is true and no email/phone add-on is already enabled
Heads up
Empty results do not burn credits.

Responses

202 Search queued or still processing - poll with the returned request_id
200 Requested page is complete (immediately cached or returned by a completed status poll)
400 Invalid parameters, including an object-valued query or missing search scope
401 Missing, invalid, or expired API credentials
402 Insufficient credits
403 Valid credentials, but the account, plan, product, subscription, or request IP is not allowed
404 Unknown request_id or a request_id not owned by this API key
429 Rate or monthly request limit exceeded
500 The queued search reached a terminal processing error; do not keep polling that request_id
503 Search or status infrastructure is temporarily unavailable; retry with backoff

A newly queued submit returns 202 Accepted. It contains the polling identifier, not the result:

{
  "success": true,
  "data": {
    "request_id": "abc12345_1737123456_1234",
    "status": "processing",
    "completed": false,
    "message": "Search request is being processed. Poll GET /person/search with request_id to check status.",
    "offset": 0,
    "limit": 10
  },
  "timestamp": "2026-01-01T00:00:00"
}

A successful terminal poll returns 200 with the completed payload:

{
  "success": true,
  "data": {
    "request_id": "abc12345_1737123456_1234",
    "status": "completed",
    "completed": true,
    "results": [
      {
        "profile_id": "johnsmith",
        "displayname": "John Smith",
        "firstname": "John",
        "middlename": "A",
        "lastname": "Smith",
        "gender": "male",
        "headline": "Senior Sales Manager at Tech Corp",
        "bio": "Enterprise sales leader with 15 years closing Fortune 500 accounts.",
        "location": "San Francisco, CA",
        "altemails": [
          "john.smith@techcorp.com",
          "john.smith@gmail.com"
        ],
        "fullphone": [
          {
            "fullphone": "+1-555-123-4567",
            "phone_type": "mobile"
          }
        ],
        "social_profiles": {
          "linkedin": {
            "url": "https://linkedin.com/in/johnsmith",
            "username": "johnsmith",
            "followers": 1200,
            "connections": 500
          }
        },
        "organizations": [
          {
            "name": "Tech Corp",
            "company_domain": "techcorp.com",
            "company_employee_count": 1200,
            "company_employee_count_range_start": 1001,
            "company_employee_count_range_end": 5000,
            "company_total_funding_raised": 25000000,
            "company_latest_funding_stage": "series b",
            "company_funding_stages": [
              "seed",
              "series a",
              "series b"
            ],
            "company_funding_rounds": [
              {
                "stage": "series b",
                "date": "2025-10-03",
                "amount": 15000000,
                "investor_names": [
                  "sequoia capital"
                ]
              }
            ],
            "company_last_funding_date": "2025-10-03",
            "company_investor_names": [
              "sequoia capital"
            ],
            "title": "Senior Sales Manager",
            "startDate": "2020-03",
            "endDate": null
          }
        ],
        "schools_info": [
          {
            "name": "University of California, Berkeley",
            "degree": "BS",
            "specialization_category": "Business",
            "startDate": "2001",
            "endDate": "2005"
          }
        ],
        "skills": [
          "enterprise sales",
          "negotiation"
        ],
        "languages": [
          "english"
        ],
        "estimated_age": 42,
        "score": 5,
        "insights": {
          "overall_summary": "Strong match: senior sales leadership at a large enterprise in the target metro.",
          "why_matched": [
            {
              "criterion": "Sales managers at Fortune 500 companies",
              "evidence_type": "work_experience",
              "confidence": "strong",
              "display_text": "Current role shows senior sales management at Tech Corp.",
              "matched_phrase": "Senior Sales Manager at Tech Corp"
            },
            {
              "criterion": "San Francisco",
              "evidence_type": "location",
              "confidence": "strong",
              "display_text": "Profile location is in the requested metro."
            }
          ],
          "query_insights": [
            {
              "subquery_idx": 0,
              "subquery": "Sales managers at Fortune 500 companies",
              "priority": "Essential",
              "match_level": "Meets Expectations",
              "short_rationale": "Senior Sales Manager at a Fortune 500 company.",
              "rationale": "Currently Senior Sales Manager at Tech Corp, a Fortune 500 enterprise.",
              "short_quotes": [
                "Senior Sales Manager at Tech Corp"
              ]
            }
          ]
        }
      }
    ],
    "offset": 0,
    "limit": 10,
    "total_estimate": 500,
    "has_more": true,
    "next_cursor": "eyJvIjoxMCwiciI6ImFiYzEyMzQ1…",
    "credits_charged": 160
  },
  "timestamp": "2026-01-01T00:00:00"
}