Search
Search talents by prompt
Find professional profiles from a natural-language description.
POST
/
v1
/
search
/
talents
/
by-prompt
Search talents by prompt
curl --request POST \
--url https://app.kalent.ai/api/v1/search/talents/by-prompt \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"prompt": "<string>",
"relatedSearchTransactionIds": [
"<string>"
]
}
'import requests
url = "https://app.kalent.ai/api/v1/search/talents/by-prompt"
payload = {
"prompt": "<string>",
"relatedSearchTransactionIds": ["<string>"]
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({prompt: '<string>', relatedSearchTransactionIds: ['<string>']})
};
fetch('https://app.kalent.ai/api/v1/search/talents/by-prompt', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.kalent.ai/api/v1/search/talents/by-prompt",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'prompt' => '<string>',
'relatedSearchTransactionIds' => [
'<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.kalent.ai/api/v1/search/talents/by-prompt"
payload := strings.NewReader("{\n \"prompt\": \"<string>\",\n \"relatedSearchTransactionIds\": [\n \"<string>\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.kalent.ai/api/v1/search/talents/by-prompt")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"prompt\": \"<string>\",\n \"relatedSearchTransactionIds\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.kalent.ai/api/v1/search/talents/by-prompt")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"prompt\": \"<string>\",\n \"relatedSearchTransactionIds\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"talents": [
{
"id": "<string>",
"firstname": "<string>",
"lastname": "<string>",
"gender": "<string>",
"city": "<string>",
"country": "<string>",
"jobTitle": "<string>",
"summary": "<string>",
"state": "<string>",
"headline": "<string>",
"photoUrl": "<string>",
"linkedinUrl": "<string>",
"currentOrganization": {
"id": "<string>",
"name": "<string>",
"logoUrl": "<string>"
},
"experiences": [
{
"organizationName": "<string>",
"title": "<string>",
"startDate": "<string>",
"endDate": "<string>",
"description": "<string>",
"isCurrent": true,
"organization": {
"logoUrl": "<string>",
"name": "<string>"
}
}
],
"educations": [
{
"schoolName": "<string>",
"schoolLogo": "<string>",
"summary": "<string>",
"degrees": [
"<string>"
],
"majors": [
"<string>"
],
"minors": [
"<string>"
],
"startDate": "<string>",
"endDate": "<string>",
"schoolDomain": "<string>"
}
],
"skills": [
"<string>"
],
"interests": [
"<string>"
],
"languages": [
{
"name": "<string>",
"proficiency": "<string>"
}
],
"certifications": [
{
"name": "<string>",
"organizationName": "<string>",
"startDate": "<string>",
"endDate": "<string>"
}
]
}
],
"estimationCount": 123,
"searchTransactionId": "<string>",
"pendingRefreshCount": 123
},
"error": {
"code": "<string>",
"message": "<string>",
"debugTrackingCode": "<string>",
"issues": [
{}
],
"details": {
"window": "<string>",
"limit": 123,
"current": 123
}
}
}First time? Set up Authentication
Learn how to authenticate your API requests with your API key.
filters array yourself, you send a single prompt and the API converts it into structured filters automatically — the same engine that powers the Kalent MCP search_talents tool. Results are ranked by best overall match.
This endpoint is the natural-language counterpart of POST /v1/search/talents. The success response is identical to that endpoint.
Only ready profiles are returned: talents that are already up to date, or that were synchronously refreshed and passed refiltering. Profiles currently being updated asynchronously are excluded from the current response and counted in pendingRefreshCount.
Request body
A natural-language description of the talent you are looking for — e.g.
"Senior React developer in Paris with 5+ years experience". The API
interprets the prompt and derives the structured filters (job title, location,
skill, years of experience, etc.) used to run the search. If the prompt cannot
be turned into any usable filter, the request returns
prompt_interpretation_failed.Array of
searchTransactionId values from previous search responses. When
provided, talents that were returned in those previous searches are excluded
from the current results. Use this field for pagination: after each
search, collect the searchTransactionId from the response and include it
(along with any earlier ones) in your next request to receive fresh,
non-overlapping results. See Pagination below.Response
Whether the request completed without errors.
Present when
success is true.Show data fields
Show data fields
Array of matching talent profiles, ordered by relevance. Up to 10 results per request.
Show Talent object
Show Talent object
Unique talent identifier.
First name.
Last name.
Gender.
City of residence.
Country of residence.
Current job title.
Professional summary.
State or region.
LinkedIn headline.
URL to profile photo.
LinkedIn profile URL.
Work experience entries.
Show properties
Show properties
Company name.
Job title.
Start date (ISO).
End date (ISO),
null if current.Role description.
Whether this is the current role.
Education entries.
Show properties
Show properties
List of skills.
List of interests.
Estimated total number of talents matching the query across the entire database.
Unique identifier for this search transaction. Pass this value in
relatedSearchTransactionIds on subsequent requests to paginate through results. Also useful for support requests and debugging.Number of matching profiles in the current fetched batch that are currently being updated asynchronously and were therefore excluded from
talents. This count is batch-scoped (not the full estimated result universe). When greater than zero, retry the same search shortly to retrieve those profiles once they are ready.Error details, present when
success is false.Show error fields
Show error fields
Machine-readable error code. One of:
validation_error, prompt_interpretation_failed, too_many_search_transactions, insufficient_api_credits, search_engine_timeout, missing_connected_linkedin_account, missing_api_key, invalid_api_key, rate_limit_exceeded, internal_error.Human-readable error description.
Unique tracking code for this request. Include it when contacting support.
Zod validation details. Only present when
code is validation_error.Pagination
Pagination works exactly like the filter-based endpoint: it uses a transaction-based pagination model instead of traditional page numbers. Send the sameprompt again and accumulate previous searchTransactionId values in the relatedSearchTransactionIds array — each new request excludes all talents from every prior transaction so you never see the same talent twice. See the Pagination section of POST /v1/search/talents for the full mechanism.
# Page 1
curl -X POST https://app.kalent.ai/api/v1/search/talents/by-prompt \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"prompt": "Senior React developer in Paris with 5+ years experience"
}'
# → response includes "searchTransactionId": "st_aaa111"
# Page 2
curl -X POST https://app.kalent.ai/api/v1/search/talents/by-prompt \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"prompt": "Senior React developer in Paris with 5+ years experience",
"relatedSearchTransactionIds": ["st_aaa111"]
}'
Non-deterministic results — Search results are not guaranteed to be identical across requests, even with the same prompt. This is by design:
- Prompt interpretation: the same prompt may be interpreted slightly differently between calls, which can shift the result pool.
- Real-time profile refresh: talent profiles are enriched and updated in real time during search. A profile that did not match moments ago may match now (and vice versa) after a refresh.
- AI-powered scoring: result ranking uses AI models whose outputs can vary slightly between calls.
- Database updates: new talents are continuously indexed and existing profiles are updated from external sources.
relatedSearchTransactionIds mechanism guarantees that you will not see the same talent twice across paginated requests, but the total pool of matching talents may shift between calls. This is inherent to a live, AI-augmented search engine and does not affect result accuracy.Read more in the Non-deterministic Results guide.Response examples
200 — Success
200 — Success
Request
curl -X POST https://app.kalent.ai/api/v1/search/talents/by-prompt \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"prompt": "Senior React developer in Paris with 5+ years experience"
}'
Response
{
"success": true,
"data": {
"talents": [
{
"id": "clx1abc2d3e4f5g6h7i8j9k0",
"firstname": "Marie",
"lastname": "Dupont",
"gender": "female",
"city": "Paris",
"country": "France",
"jobTitle": "Senior Software Engineer",
"summary": "Full-stack engineer with 8 years of experience...",
"state": "Île-de-France",
"headline": "Senior Software Engineer at Acme Corp",
"photoUrl": "https://media.licdn.com/dms/image/...",
"linkedinUrl": "https://www.linkedin.com/in/marie-dupont",
"currentOrganization": {
"id": "org_abc123",
"name": "Acme Corp",
"logoUrl": "https://media.licdn.com/dms/image/..."
},
"experiences": [
{
"organizationName": "Acme Corp",
"title": "Senior Software Engineer",
"startDate": "2021-03-01T00:00:00.000Z",
"endDate": null,
"description": "Leading the frontend team...",
"isCurrent": true,
"organization": {
"logoUrl": "https://media.licdn.com/dms/image/...",
"name": "Acme Corp"
}
}
],
"educations": [
{
"schoolName": "École Polytechnique",
"schoolLogo": "https://media.licdn.com/dms/image/...",
"summary": null,
"degrees": ["Master of Science"],
"majors": ["Computer Science"],
"minors": [],
"startDate": "2013-09-01T00:00:00.000Z",
"endDate": "2017-06-30T00:00:00.000Z",
"schoolDomain": "polytechnique.edu"
}
],
"skills": ["TypeScript", "React", "Node.js", "PostgreSQL"],
"interests": ["Open Source", "Machine Learning"],
"languages": [
{ "name": "French", "proficiency": "native_or_bilingual" },
{ "name": "English", "proficiency": "full_professional" }
],
"certifications": [
{
"name": "AWS Solutions Architect",
"organizationName": "Amazon Web Services",
"startDate": "2023-01-15T00:00:00.000Z",
"endDate": "2026-01-15T00:00:00.000Z"
}
]
}
],
"estimationCount": 2430,
"searchTransactionId": "st_xyz789",
"pendingRefreshCount": 0
}
}
422 — Prompt interpretation failed
422 — Prompt interpretation failed
Returned when the prompt could not be turned into any usable filter. Rephrase your prompt with more concrete search criteria (a role, a location, a skill, etc.).
Request
curl -X POST https://app.kalent.ai/api/v1/search/talents/by-prompt \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"prompt": "someone good"
}'
Response
{
"success": false,
"error": {
"code": "prompt_interpretation_failed",
"message": "Could not interpret the prompt into any usable search filter. Please rephrase with more concrete criteria such as a job title, location, or skill.",
"debugTrackingCode": "V1StGXR8_Z5jdHi6B-myT"
}
}
400 — Validation error
400 — Validation error
Returned when the request body does not match the expected schema — for example when
prompt is missing or empty.Request
curl -X POST https://app.kalent.ai/api/v1/search/talents/by-prompt \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{}'
Response
{
"success": false,
"error": {
"code": "validation_error",
"message": "Validation failed",
"debugTrackingCode": "V1StGXR8_Z5jdHi6B-myT",
"issues": [
{
"code": "invalid_type",
"expected": "string",
"received": "undefined",
"path": ["prompt"],
"message": "Required"
}
]
}
}
401 — Authentication error
401 — Authentication error
Returned when the API key is missing or invalid.
Request
curl -X POST https://app.kalent.ai/api/v1/search/talents/by-prompt \
-H "Content-Type: application/json" \
-d '{
"prompt": "Senior React developer in Paris with 5+ years experience"
}'
Response (missing key)
{
"success": false,
"error": {
"code": "missing_api_key",
"message": "Missing API key",
"debugTrackingCode": "V1StGXR8_Z5jdHi6B-myT"
}
}
Response (invalid key)
{
"success": false,
"error": {
"code": "invalid_api_key",
"message": "Invalid API key",
"debugTrackingCode": "V1StGXR8_Z5jdHi6B-myT"
}
}
402 — Insufficient API credits
402 — Insufficient API credits
Returned when your account does not have enough API credits to run the search. Top up your credits and retry.
Response
{
"success": false,
"error": {
"code": "insufficient_api_credits",
"message": "Insufficient API credits to perform this search.",
"debugTrackingCode": "V1StGXR8_Z5jdHi6B-myT"
}
}
Previous
Accepted filter valuesReference of all filter types and their accepted values for the Search Talents endpoint.
Next
⌘I
Search talents by prompt
curl --request POST \
--url https://app.kalent.ai/api/v1/search/talents/by-prompt \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--data '
{
"prompt": "<string>",
"relatedSearchTransactionIds": [
"<string>"
]
}
'import requests
url = "https://app.kalent.ai/api/v1/search/talents/by-prompt"
payload = {
"prompt": "<string>",
"relatedSearchTransactionIds": ["<string>"]
}
headers = {
"x-api-key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'x-api-key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({prompt: '<string>', relatedSearchTransactionIds: ['<string>']})
};
fetch('https://app.kalent.ai/api/v1/search/talents/by-prompt', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://app.kalent.ai/api/v1/search/talents/by-prompt",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'prompt' => '<string>',
'relatedSearchTransactionIds' => [
'<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"x-api-key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://app.kalent.ai/api/v1/search/talents/by-prompt"
payload := strings.NewReader("{\n \"prompt\": \"<string>\",\n \"relatedSearchTransactionIds\": [\n \"<string>\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("x-api-key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://app.kalent.ai/api/v1/search/talents/by-prompt")
.header("x-api-key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"prompt\": \"<string>\",\n \"relatedSearchTransactionIds\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://app.kalent.ai/api/v1/search/talents/by-prompt")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["x-api-key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"prompt\": \"<string>\",\n \"relatedSearchTransactionIds\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"talents": [
{
"id": "<string>",
"firstname": "<string>",
"lastname": "<string>",
"gender": "<string>",
"city": "<string>",
"country": "<string>",
"jobTitle": "<string>",
"summary": "<string>",
"state": "<string>",
"headline": "<string>",
"photoUrl": "<string>",
"linkedinUrl": "<string>",
"currentOrganization": {
"id": "<string>",
"name": "<string>",
"logoUrl": "<string>"
},
"experiences": [
{
"organizationName": "<string>",
"title": "<string>",
"startDate": "<string>",
"endDate": "<string>",
"description": "<string>",
"isCurrent": true,
"organization": {
"logoUrl": "<string>",
"name": "<string>"
}
}
],
"educations": [
{
"schoolName": "<string>",
"schoolLogo": "<string>",
"summary": "<string>",
"degrees": [
"<string>"
],
"majors": [
"<string>"
],
"minors": [
"<string>"
],
"startDate": "<string>",
"endDate": "<string>",
"schoolDomain": "<string>"
}
],
"skills": [
"<string>"
],
"interests": [
"<string>"
],
"languages": [
{
"name": "<string>",
"proficiency": "<string>"
}
],
"certifications": [
{
"name": "<string>",
"organizationName": "<string>",
"startDate": "<string>",
"endDate": "<string>"
}
]
}
],
"estimationCount": 123,
"searchTransactionId": "<string>",
"pendingRefreshCount": 123
},
"error": {
"code": "<string>",
"message": "<string>",
"debugTrackingCode": "<string>",
"issues": [
{}
],
"details": {
"window": "<string>",
"limit": 123,
"current": 123
}
}
}
