linkedin_search_people 10 credits

Find people on LinkedIn by keywords and filters. The right tool when you have a name, role, or 'who is the X at Y' question without a profile URL. Pass keywords (free text: name, title, or both) and any of first_name, last_name, title, school, current_company, past_company. If keywords is omitted it is derived from the name or title filters; school or company filters alone are rejected with INVALID_INPUT, so include keywords with those. Company filters accept a company name, slug, numeric id, or URN. current_company names are matched by LinkedIn's own company search: typo-tolerant and fuzzy, so results can include people whose headline merely mentions the company; when you need exact filtering, pass the numeric id or URN (linkedin_get_company returns both). past_company names are resolved to an id for you. Costs 10 credits including the first 10 results; each further 10 results add 1 credit (limit max 30; trial keys max 10). A cursor page is a NEW call priced the same way by its own limit, so one limit=30 call is much cheaper than three limit=10 pages; prefer a larger limit over paginating. Do NOT combine a past_company NAME or a company-URL filter with limit=30: resolving those spends one of the call's three internal fetches, so that combination is rejected; keep limit<=20 with them or pass the numeric id. current_company names never spend a fetch, so they combine with any limit. Returns name, position, location, urn, public_identifier per result, a cursor for the next page, and total_matches. Results with is_anonymous=true are private profiles; do not pass them to linkedin_get_profile. For one known person with a URL/slug, call linkedin_get_profile directly instead.

Part of the LinkedIn toolset: /docs/linkedin.

Parameters#

ParamRequiredTypeDescription
keywordsnostringFree-text query: a name, a title, or both.
first_namenostringFirst-name filter, exact match.
last_namenostringLast-name filter, exact match.
titlenostringCurrent job title filter.
schoolnostringSchool or university name filter.
current_companynostringCompany name, slug, numeric id, or urn:li:fsd_company URN. Names are fuzzy-matched by LinkedIn; ids and URNs filter exactly.
past_companynostringSame accepted forms as current_company; names are resolved to an id server-side.
limitnointegerHow many results to return.
cursornostringCursor from a previous page.
freshnessnostringrecent (default) serves cached data from the last few hours when available; realtime forces a live fetch for +2 credits (refunded if we fall back to cached data). Trial keys are cached-only and reject realtime with TRIAL_CAP_EXCEEDED; paying upgrades this same key to unlock it.
max_creditsnointegerSpend ceiling for this one call. The call is rejected (nothing charged) if its quote exceeds this. Only the quote is ever reserved, never this ceiling.

REST#

GET /v1/linkedin/search · auth: required · metered: true

Request
curl "https://api.veezee.io/v1/linkedin/search?keywords=CTO&current_company=anthropic" \
  -H "Authorization: Bearer $VEEZEE_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)"

MCP#

tools/call
{
  "method": "tools/call",
  "params": {
    "name": "linkedin_search_people",
    "arguments": {
      "keywords": "CTO",
      "current_company": "anthropic"
    }
  }
}

Input examples#

Role at a company

{
  "keywords": "CTO",
  "current_company": "anthropic"
}

Name search, more results

{
  "keywords": "John Smith",
  "title": "software engineer",
  "limit": 30
}

Next page

{
  "keywords": "CTO",
  "current_company": "anthropic",
  "cursor": "<cursor from previous response>"
}

Output#

Returns a people_search envelope. Full field list: /docs/fields#people_search.

Errors#

REST returns application/problem+json; MCP returns the same content as an error result. message is written as the next-turn instruction.

CodeHTTP statusRetriableMeaning
INVALID_INPUT400noA parameter failed validation. Check param and message for what to fix.
NOT_FOUND404noNothing matches the given identifier or URL.
UNAUTHORIZED401noInvalid, revoked, or unusable API key.
NOT_ENTITLED403noThis account is not enabled for the platform you called.
INSUFFICIENT_CREDITS402noYour balance can't cover this call's quote. Check get_usage or add credits.
QUOTE_EXCEEDS_MAX_CREDITS402noThe call's quote is higher than the max_credits you set. Nothing was charged.
IDEMPOTENCY_KEY_REQUIRED400noThis is a metered call; send an Idempotency-Key header.
IDEMPOTENCY_KEY_REUSED409noThat Idempotency-Key was already used with different arguments. Use a new key for a new call.
CONCURRENCY_LIMIT429yesToo many calls in flight for this key's plan. Wait for one to finish.
RATE_LIMITED429yesToo many calls per minute for this key's plan. Back off and retry.
TRIAL_CAP_EXCEEDED403noA trial-only limit was hit (concurrency, rate, search size, or realtime fetches).
BUDGET_EXHAUSTED503noA configured spend budget has been used up.
UPSTREAM_UNAVAILABLE502yesLinkedIn data wasn't reachable. Safe to retry.
PAYLOAD_TOO_LARGE413noThe request or response exceeded the size limit.
INTERNAL500yesSomething failed on our side. Safe to retry.
AUTH_REQUIRED401no
KEY_REQUIRED401noNo API key was sent. Mint one free at POST /v1/keys/mint and retry.
Errors a payment can fix: the offer fields

Errors a payment can fix add fields to the base error shape. INSUFFICIENT_CREDITS, TRIAL_CAP_EXCEEDED, and BUDGET_EXHAUSTED carry upgrade_url (a link to hand to your human) and offer, its machine-readable twin. RATE_LIMITED and CONCURRENCY_LIMIT carry both on trial accounts only, where a paid plan raises the limit.

Fields inside offer:

After payment, follow resume: INSUFFICIENT_CREDITS retries the same call with the same Idempotency-Key; TRIAL_CAP_EXCEEDED and BUDGET_EXHAUSTED retry with a fresh key; the two limit codes clear on their own with back-off, payment only raises the limit. INSUFFICIENT_CREDITS also sets credits_required: the credits the failed call needed. The failed attempt charged nothing.