Search for people
Search for people with a natural-language query.
/v1/searchAuthenticated with your x-api-key. See Authentication.
Request
POST /v1/search
Host: search-api.xverum.com
x-api-key: XVERUM-API-KEY
Content-Type: application/jsonBody
| Field | Type | Required | Constraints | Description |
|---|---|---|---|---|
query | string | yes | 1–500 chars, trimmed, must not be blank | Natural-language search query |
page | integer | no | ≥ 1, default 1 | 1-based page number |
page_size | integer | no | 1–100, default 10 | Results per page |
Example body
{
"query": "senior Python developers with Kubernetes in Seattle",
"page": 1,
"page_size": 10
}Pagination
Offset-based:
page— integer,≥ 1(default1).page_size— integer, `1` to `100` (default10).page * page_sizemust not exceed 1000 — the max result window.
A page_size outside 1–100 returns 422 validation_error; a page * page_size over 1000 returns 400 invalid_pagination. Deep pagination over the entire corpus is intentionally unsupported — refine the query instead.
total_count is an estimate of total matches, not an exact count. Use it as a rough size signal, not for precise "page N of M" math.
Example
curl -X POST https://search-api.xverum.com/v1/search \
-H "x-api-key: XVERUM-API-KEY" \
-H "Content-Type: application/json" \
-d '{
"query": "senior Python developers with Kubernetes in Seattle"
}'Response — 200 OK
| Field | Type | Description |
|---|---|---|
result_type | string | Always people for this endpoint — discriminates the shape of results |
results | Profile[] | Matched profiles (see schema below) |
total_count | integer | Estimated total number of matches |
page | integer | 1-based page number echoed back |
page_size | integer | Results per page echoed back |
credits_used | integer | Credits deducted on this call (1 per returned result) |
credits_remaining | integer | Credits left after this call — a best-effort fresh read from billing; on a transient billing outage it falls back to the balance seen at auth time |
request_id | string | Correlation id — also returned in the X-Request-Id header |
Every response also carries X-Request-Id and the X-RateLimit-* headers (see Rate limits).
To get the complete profile — employment history, profile summary and seniority — pass a result's id to GET /v1/profiles/{id}.
Profile schema
| Field | Type | Description |
|---|---|---|
id | string | Opaque profile id; pass to GET /v1/profiles/{id} |
social_url | string | null | Person social URL |
full_name | string | Full name |
headline | string | null | Person social headline or summary |
location | string | null | Location string |
company_name | string | null | Most recent employer |
position | string | null | Most recent job title |
industry | string | null | Industry vertical |
evidence_summary | string | How recently this profile was verified, from its refresh date — Verified last 30 days through Verified over 120 days ago |
Example response
{
"result_type": "people",
"results": [
{
"id": "a1b2c3d4",
"social_url": "https://www.linkedin.com/in/jane-doe-sea",
"full_name": "Jane Doe",
"headline": "Senior Python Engineer at Acme",
"location": "Seattle, WA",
"company_name": "Acme",
"position": "Senior Python Engineer",
"industry": "software",
"evidence_summary": "Verified last 30 days"
},
…
],
"total_count": 128,
"page": 1,
"page_size": 10,
"credits_used": 1,
"credits_remaining": 4999,
"request_id": "8b1d4f0c12a44b7a"
}Billing
Each profile returned in results consumes 1 credit from your account, echoed back as credits_used; credits_remaining shows the balance left. A request that returns 10 profiles spends 10 credits.
credits_remaining is read fresh from billing on each successful call and is best-effort: if billing is briefly unavailable it falls back to the balance seen at authentication. Treat it as an indicative post-call balance, not a settled ledger figure.
Errors
All /v1 errors use the structured envelope (see Authentication):
| Status | error.code | Condition |
|---|---|---|
400 | off_topic_query | Query is not a people-search query |
400 | invalid_pagination | page * page_size exceeds the 1000 max result window |
401 | invalid_api_key | Missing or invalid API key |
402 | out_of_credits | Out of credits — the envelope carries an upgrade_url to top up |
403 | account_not_authorized | Account not authorized |
422 | validation_error | Body failed validation (e.g. query blank or longer than 500 chars) |
429 | rate_limited | Rate limit exceeded — see Rate limits |
502 | upstream_unavailable | An upstream dependency failed — retry shortly |
503 | search_unavailable | Search is temporarily saturated or unreachable — retry shortly |
503 | auth_unavailable | Authentication is briefly unreachable — retry shortly |
503 | classification_degraded | Query understanding is degraded — retry shortly |
{
"error": {
"code": "off_topic_query",
"message": "Query is not a people-search query.",
"request_id": "8b1d4f0c12a44b7a"
}
}