API Reference
Search, preview, autocomplete, enrich, and fetch contacts for professional profiles — from your own stack, with precise filters and structured, ready-to-use data.
Introduction
The RecruitKar API is a REST interface for people search and enrichment. You send JSON, we return structured professional profiles. Five endpoints do everything:
| Endpoint | Does | Cost |
|---|---|---|
| POST/v1/person/search | Find matching profiles | 1 / profile |
| POST/v1/person/preview | Count matches (no profiles) | 1 / call |
| POST/v1/person/search/autocomplete | Valid values for a filter field | Free |
| POST/v1/person/enrich | Full record for a profile URL | 25 / profile |
| POST/v1/person/contact | Email + phone for a profile URL | 3 / contact |
All requests are POST with a JSON body, over HTTPS.
skills is available to filter on but is not returned — call Enrich on the profiles you want to hydrate. Emails and phone numbers come from Contact.Quick start
Create a key on the API Keys page, then make your first search:
curl -X POST https://api.recruitkar.com/v1/person/search \
-H "Authorization: Bearer rk_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"filters": {
"op": "and",
"conditions": [
{ "field": "title", "type": "(.)", "value": "Software Engineer" },
{ "field": "skills", "type": "in", "value": ["React", "Node.js"] }
]
},
"limit": 10
}'You get back a profiles array, a total_count, and a next_cursor for paging. Credits charged and remaining come back in the response headers.
Authentication
Every request authenticates with your API key as a bearer token. The base URL is:
https://api.recruitkar.com/v1Authorization: Bearer rk_live_your_key_here
Content-Type: application/jsonKeys are created and revoked on the API Keys page. A key is shown once at creation — store it securely. Requests without a valid key return 401 UNAUTHORIZED. Every response carries an x-api-version header identifying the version that served it.
Search
POST/v1/person/searchReturn matching profiles. Billed 1 credit per profile returned; a request that errors is not charged.
At a glance
| Method | POST/v1/person/search |
| Auth | Bearer token |
| Required | filters |
| Optional | limit (1–100, default 25) · cursor |
| Response | { profiles, total_count, next_cursor } |
| Cost | 1 credit / profile returned |
Filters
Search takes a filters object — either a single condition or a group that combines conditions with and / or. A condition has three keys: field, type (the operator — note the key is type, not operator), and value.
{ "field": "skills", "type": "(.)", "value": "Rust" }{
"op": "and",
"conditions": [
{ "field": "title", "type": "(.)", "value": "Product Manager" },
{ "field": "years_experience", "type": "=>", "value": 5 },
{
"op": "or",
"conditions": [
{ "field": "location", "type": "in", "value": ["San Francisco, California, United States"] },
{ "field": "location", "type": "in", "value": ["New York, New York, United States"] }
]
}
]
}Fields
Every field you can filter on, its type, allowed operators, whether it supports autocomplete, and an example value.
| Field | Type | Operators | Autocomplete | Example |
|---|---|---|---|---|
title | text | (.), in, not_in, =, != | ✓ | "Software Engineer" |
past_title | text | (.), in, not_in, =, != | ✓ | "Data Analyst" |
company | text | (.), in, not_in, =, != | ✓ | "Google" |
past_company | text | (.), in, not_in, =, != | ✓ | "Microsoft" |
seniority | text | (.), in, not_in, = | ✓ | "Senior" |
company_size | text | =, in, not_in | — | "1001-5000" |
company_type | text | =, in, not_in | ✓ | "Public Company" |
industry | text[] | (.), in, not_in | ✓ | "Computer Software" |
degree | text | (.), in, not_in | ✓ | "Bachelor of Science" |
school | text | (.), in, not_in | ✓ | "Stanford University" |
field_of_study | text | (.), in, not_in | ✓ | "Computer Science" |
location | text | (.), in, not_in, = | ✓ | "San Francisco, California, United States" |
language | text[] | (.), in, not_in | ✓ | "English" |
skills | text[] | (.), in, not_in | ✓ | "Python" |
years_experience | number | =, !=, >, <, =>, =< | — | 5 |
recently_changed_jobs | boolean | = | — | true |
Operators
The type of a condition is one of:
| Operator | Meaning | Works on |
|---|---|---|
(.) | Contains — case-insensitive substring / fuzzy match | text, text[] |
in | Matches any value in a list | text, text[], number |
not_in | Matches none of the values in a list | text, text[], number |
= | Exact match | text, number, boolean |
!= | Not an exact match | text, number |
> | Greater than | number |
< | Less than | number |
=> | Greater than or equal to | number |
=< | Less than or equal to | number |
Response
{
"profiles": [
{
"id": "9f340bef557aa20053661f25",
"name": "Jane Smith",
"headline": "Senior Software Engineer",
"summary": null,
"location": "San Francisco, California, United States",
"linkedin_url": "https://www.linkedin.com/in/janesmith",
"twitter_url": null,
"profile_picture_url": "https://api.recruitkar.com/v1/media/AbC123...",
"years_experience": 7,
"connections": null,
"skills": [],
"languages": [],
"current_experience": { "title": "Senior Software Engineer", "company": "Acme Corp", "location": "San Francisco", "start_date": "2021-03-01", "end_date": null, "is_current": true },
"past_experience": [
{ "title": "Software Engineer", "company": "Globex", "location": null, "start_date": "2018-06-01", "end_date": "2021-02-01", "is_current": false }
],
"education": [
{ "degree": "BS", "field_of_study": "Computer Science", "institution": "Stanford University", "start_date": "2014", "end_date": "2018" }
]
}
],
"total_count": 48213,
"next_cursor": "eyJ..."
}https://api.recruitkar.com/v1/media/...). The URLs are safe to embed directly in an <img> tag — no key required.Pagination
A response includes next_cursor when more results exist. To fetch the next page, repeat the request with the same filters and set cursor to that value. When next_cursor is null, you have reached the end.
{ "filters": { }, "limit": 25, "cursor": "eyJ..." }Preview
POST/v1/person/previewReturn the match count for a filter set, without the profiles. 1 credit per call — size a search before you spend.
At a glance
| Method | POST/v1/person/preview |
| Required | filters |
| Response | { match_count } |
| Cost | 1 credit / call |
{ "filters": { "field": "skills", "type": "(.)", "value": "Rust" } }{ "match_count": 8421 }Autocomplete
POST/v1/person/search/autocompleteSuggest real values for a filter field. Use it to turn free text into exact values for in filters. Free.
At a glance
| Method | POST/v1/person/search/autocomplete |
| Required | field · query |
| Optional | limit (1–100, default 20) · filters |
| Response | { suggestions: [ string ] } |
| Cost | Free |
Supported on any field marked ✓ in the Search Fields table (title, company, location, skills, seniority, industry, degree, school, languages, and more). Pass a partial query for type-ahead, or an empty query to get the most common values. Optional filters scope the suggestions to a subset of the population.
{ "field": "location", "query": "san fran", "limit": 5 }{
"suggestions": [
"San Francisco, California, United States",
"San Francisco Bay Area"
]
}Recommended flow: autocomplete a value → use the exact string in an in filter → search.
Enrich
POST/v1/person/enrichReturn the complete profile record for people you know by profile URL. Billed 25 credits per matched profile.
At a glance
| Method | POST/v1/person/enrich |
| Required | linkedin_urls |
| Limits | Up to 25 profile URLs per request |
| Response | Array of matches, one per URL |
| Cost | 25 credits / matched profile |
Enrich returns the full record: skills, summary, languages, connections, and detailed employment and education. Identifiers with no match are not charged.
{ "linkedin_urls": ["https://www.linkedin.com/in/janesmith"] }[
{
"matched_on": "https://www.linkedin.com/in/janesmith",
"match_type": "linkedin_url",
"matches": [
{
"confidence_score": 1,
"person": {
"id": "9f340bef557aa20053661f25",
"name": "Jane Smith",
"summary": "Engineer focused on distributed systems...",
"skills": ["Python", "AWS", "Kafka"],
"languages": ["English"],
"connections": 507,
"current_experience": { "title": "Senior Software Engineer", "company": "Acme Corp", "is_current": true },
"past_experience": [],
"education": []
}
}
]
}
]Contact
POST/v1/person/contactFetch verified emails and phone numbers by profile URL. Billed 3 credits per contact found.
At a glance
| Method | POST/v1/person/contact |
| Required | linkedin_urls |
| Limits | Up to 25 profile URLs per request |
| Response | Array of matches, one per URL |
| Cost | 3 credits / contact found |
Returns business and personal emails plus phone numbers. Identifiers with no contact found are not charged. Each email carries a deliverability status: deliverable, catch_all, invalid, or unknown.
{ "linkedin_urls": ["https://www.linkedin.com/in/janesmith"] }[
{
"matched_on": "https://www.linkedin.com/in/janesmith",
"match_type": "linkedin_url",
"matches": [
{
"confidence_score": 1,
"person_data": {
"contact": {
"business_emails": [ { "email": "[email protected]", "status": "deliverable" } ],
"personal_emails": [ { "email": "[email protected]", "status": "deliverable" } ],
"phone_numbers": ["+1-555-0100"]
}
}
}
]
}
]Person object
The profile shape returned inside profiles[] (Search) and matches[].person (Enrich):
| Field | Type | Description |
|---|---|---|
id | string | Stable, opaque identifier for the profile |
name | string | Full name |
headline | string | Professional headline |
summary | string | null | About / bio text — Enrich only |
location | string | Location (city, state, country) |
linkedin_url | string | Public profile URL |
twitter_url | string | null | Twitter / X profile, if available |
profile_picture_url | string | null | Avatar URL, served via the RecruitKar media proxy |
years_experience | number | null | Total years of professional experience |
connections | number | null | Network size — Enrich only |
skills | string[] | Skills — Enrich only (filter-only on Search) |
languages | string[] | Languages — Enrich only |
current_experience | object | null | Current role — see Experience object |
past_experience | object[] | Past roles — see Experience object |
education | object[] | Education — see Education object |
Experience object
The shape of current_experience and each item in past_experience:
| Field | Type | Description |
|---|---|---|
title | string | null | Role title |
company | string | null | Employer name |
location | string | null | Role location |
start_date | string | null | ISO start date |
end_date | string | null | ISO end date; null for the current role |
is_current | boolean | Whether this is the current role |
Education object
Each item in education:
| Field | Type | Description |
|---|---|---|
degree | string | null | Degree earned |
field_of_study | string | null | Field of study |
institution | string | null | Institution name |
start_date | string | null | Start year |
end_date | string | null | End year |
Errors
Errors always return the same shape, with a stable code and a human-readable message:
{ "error": { "code": "INSUFFICIENT_CREDITS", "message": "This request costs up to 25 credits; your balance is 12." } }| Code | HTTP | When it happens |
|---|---|---|
INVALID_QUERY | 400 | A filter field, operator, value, or identifier is invalid — see the message |
UNAUTHORIZED | 401 | Missing or invalid API key — check the Authorization header |
INSUFFICIENT_CREDITS | 402 | Not enough credits — top up to continue |
FORBIDDEN | 403 | Account suspended — contact your account manager |
RATE_LIMITED | 429 | Too many requests — retry after a short backoff |
UPSTREAM_UNAVAILABLE | 503 | Temporary issue — retry with exponential backoff |
Rate limits & billing
Rate limit: 60 requests per minute per key. Exceeding it returns 429 RATE_LIMITED.
| Endpoint | Price | Notes |
|---|---|---|
| Search | 1 credit / profile returned | Charged for the profiles you receive; unreturned page slots refunded |
| Preview | 1 credit / call | Match count for a filter set (runs a search to read it) |
| Autocomplete | Free | Filter-value suggestions |
| Enrich | 25 credits / matched profile | The complete profile record; unmatched URLs refunded |
| Contact | 3 credits / contact found | Not-found identifiers refunded |
Billed responses include x-credits-charged and x-credits-remaining headers. Top-ups are handled by your account manager.