> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kalent.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Search talents by prompt

> Find professional profiles from a natural-language description.

<Card title="First time? Set up Authentication" icon="key" href="/authentication">
  Learn how to authenticate your API requests with your API key.
</Card>

Search the Kalent talent database with a plain-language description of who you are looking for. Instead of building a `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`](/api-reference/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

<ParamField body="prompt" type="string" required>
  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`.
</ParamField>

<ParamField body="relatedSearchTransactionIds" type="string[]">
  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](#pagination) below.
</ParamField>

## Response

<ResponseField name="success" type="boolean">
  Whether the request completed without errors.
</ResponseField>

<ResponseField name="data" type="object">
  Present when `success` is `true`.

  <Expandable title="data fields">
    <ResponseField name="talents" type="object[]">
      Array of matching talent profiles, ordered by relevance. Up to 10 results per request.

      <Expandable title="Talent object">
        <ResponseField name="id" type="string">
          Unique talent identifier.
        </ResponseField>

        <ResponseField name="firstname" type="string">
          First name.
        </ResponseField>

        <ResponseField name="lastname" type="string">
          Last name.
        </ResponseField>

        <ResponseField name="gender" type="string">
          Gender.
        </ResponseField>

        <ResponseField name="city" type="string">
          City of residence.
        </ResponseField>

        <ResponseField name="country" type="string">
          Country of residence.
        </ResponseField>

        <ResponseField name="jobTitle" type="string">
          Current job title.
        </ResponseField>

        <ResponseField name="summary" type="string">
          Professional summary.
        </ResponseField>

        <ResponseField name="state" type="string">
          State or region.
        </ResponseField>

        <ResponseField name="headline" type="string">
          LinkedIn headline.
        </ResponseField>

        <ResponseField name="photoUrl" type="string">
          URL to profile photo.
        </ResponseField>

        <ResponseField name="linkedinUrl" type="string">
          LinkedIn profile URL.
        </ResponseField>

        <ResponseField name="currentOrganization" type="object">
          Current employer.

          <Expandable title="properties">
            <ResponseField name="id" type="string">Organization ID.</ResponseField>
            <ResponseField name="name" type="string">Company name.</ResponseField>
            <ResponseField name="logoUrl" type="string">Company logo URL.</ResponseField>
          </Expandable>
        </ResponseField>

        <ResponseField name="experiences" type="object[]">
          Work experience entries.

          <Expandable title="properties">
            <ResponseField name="organizationName" type="string">Company name.</ResponseField>
            <ResponseField name="title" type="string">Job title.</ResponseField>
            <ResponseField name="startDate" type="string">Start date (ISO).</ResponseField>
            <ResponseField name="endDate" type="string">End date (ISO), `null` if current.</ResponseField>
            <ResponseField name="description" type="string">Role description.</ResponseField>
            <ResponseField name="isCurrent" type="boolean">Whether this is the current role.</ResponseField>

            <ResponseField name="organization" type="object">
              <Expandable title="properties">
                <ResponseField name="logoUrl" type="string">Company logo URL.</ResponseField>
                <ResponseField name="name" type="string">Company name.</ResponseField>
              </Expandable>
            </ResponseField>
          </Expandable>
        </ResponseField>

        <ResponseField name="educations" type="object[]">
          Education entries.

          <Expandable title="properties">
            <ResponseField name="schoolName" type="string">Institution name.</ResponseField>
            <ResponseField name="schoolLogo" type="string">School logo URL.</ResponseField>
            <ResponseField name="summary" type="string">Education summary.</ResponseField>
            <ResponseField name="degrees" type="string[]">Degrees obtained.</ResponseField>
            <ResponseField name="majors" type="string[]">Major fields of study.</ResponseField>
            <ResponseField name="minors" type="string[]">Minor fields of study.</ResponseField>
            <ResponseField name="startDate" type="string">Start date.</ResponseField>
            <ResponseField name="endDate" type="string">End date.</ResponseField>
            <ResponseField name="schoolDomain" type="string">School website domain.</ResponseField>
          </Expandable>
        </ResponseField>

        <ResponseField name="skills" type="string[]">
          List of skills.
        </ResponseField>

        <ResponseField name="interests" type="string[]">
          List of interests.
        </ResponseField>

        <ResponseField name="languages" type="object[]">
          Spoken languages.

          <Expandable title="properties">
            <ResponseField name="name" type="string">Language name.</ResponseField>
            <ResponseField name="proficiency" type="string">Proficiency level.</ResponseField>
          </Expandable>
        </ResponseField>

        <ResponseField name="certifications" type="object[]">
          Professional certifications.

          <Expandable title="properties">
            <ResponseField name="name" type="string">Certification name.</ResponseField>
            <ResponseField name="organizationName" type="string">Issuing organization.</ResponseField>
            <ResponseField name="startDate" type="string">Issue date.</ResponseField>
            <ResponseField name="endDate" type="string">Expiry date.</ResponseField>
          </Expandable>
        </ResponseField>
      </Expandable>
    </ResponseField>

    <ResponseField name="estimationCount" type="number">
      Estimated total number of talents matching the query across the entire database.
    </ResponseField>

    <ResponseField name="searchTransactionId" type="string">
      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.
    </ResponseField>

    <ResponseField name="pendingRefreshCount" type="number">
      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.
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="error" type="object">
  Error details, present when `success` is `false`.

  <Expandable title="error fields">
    <ResponseField name="code" type="string">
      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`.
    </ResponseField>

    <ResponseField name="message" type="string">
      Human-readable error description.
    </ResponseField>

    <ResponseField name="debugTrackingCode" type="string">
      Unique tracking code for this request. Include it when contacting support.
    </ResponseField>

    <ResponseField name="issues" type="object[]">
      Zod validation details. Only present when `code` is `validation_error`.
    </ResponseField>

    <ResponseField name="details" type="object">
      Rate limit details. Only present when `code` is `rate_limit_exceeded`.

      <Expandable title="details fields">
        <ResponseField name="window" type="string">
          The time window that was exceeded. One of: `minute`, `hour`, `day`, `month`.
        </ResponseField>

        <ResponseField name="limit" type="number">
          Maximum number of requests allowed in this window.
        </ResponseField>

        <ResponseField name="current" type="number">
          Number of requests already made in this window.
        </ResponseField>
      </Expandable>
    </ResponseField>
  </Expandable>
</ResponseField>

## Pagination

Pagination works exactly like the filter-based endpoint: it uses a **transaction-based pagination** model instead of traditional page numbers. Send the **same `prompt`** 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`](/api-reference/search-talents#pagination) for the full mechanism.

```bash theme={null}
# 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"]
  }'
```

<Warning>
  **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.

  The `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](/non-deterministic-results) guide.
</Warning>

## Response examples

<AccordionGroup>
  <Accordion title="200 — Success">
    ```bash Request theme={null}
    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"
      }'
    ```

    ```json Response theme={null}
    {
      "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
      }
    }
    ```
  </Accordion>

  <Accordion title="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.).

    ```bash Request theme={null}
    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"
      }'
    ```

    ```json Response theme={null}
    {
      "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"
      }
    }
    ```
  </Accordion>

  <Accordion title="400 — Validation error">
    Returned when the request body does not match the expected schema — for example when `prompt` is missing or empty.

    ```bash Request theme={null}
    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 '{}'
    ```

    ```json Response theme={null}
    {
      "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"
          }
        ]
      }
    }
    ```
  </Accordion>

  <Accordion title="401 — Authentication error">
    Returned when the API key is missing or invalid.

    ```bash Request theme={null}
    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"
      }'
    ```

    ```json Response (missing key) theme={null}
    {
      "success": false,
      "error": {
        "code": "missing_api_key",
        "message": "Missing API key",
        "debugTrackingCode": "V1StGXR8_Z5jdHi6B-myT"
      }
    }
    ```

    ```json Response (invalid key) theme={null}
    {
      "success": false,
      "error": {
        "code": "invalid_api_key",
        "message": "Invalid API key",
        "debugTrackingCode": "V1StGXR8_Z5jdHi6B-myT"
      }
    }
    ```
  </Accordion>

  <Accordion title="402 — Insufficient API credits">
    Returned when your account does not have enough API credits to run the search. Top up your credits and retry.

    ```json Response theme={null}
    {
      "success": false,
      "error": {
        "code": "insufficient_api_credits",
        "message": "Insufficient API credits to perform this search.",
        "debugTrackingCode": "V1StGXR8_Z5jdHi6B-myT"
      }
    }
    ```
  </Accordion>
</AccordionGroup>
