> ## 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.

# Extract search from prompt

> Turn a job description into filters and qualification criteria, without running a search.

> **[First time? Set up Authentication](/authentication.md)**
>
> Learn how to authenticate your API requests with your API key.

Turn a job description into the `filters` and `qualificationCriterias` used by [qualified search](/api-reference/search-talents-qualified.md) and by [talent-pool estimation](/api-reference/search-talents-estimation.md). This endpoint stops at extraction: it does not return profiles.

The interpretation is the same as [qualified search by prompt](/api-reference/search-talents-qualified-by-prompt.md). The filters are written for the **gate** engine, which is the mode qualified search always runs in. See [Search modes](/api-reference/search-talents.md#search-modes).

Post `data` as-is to `POST /v1/search/talents/estimation`. Post it to `POST /v1/search/talents/qualified` as well: if `qualificationCriterias` is empty, add at least one criterion first, because qualified search requires one. `POST /v1/search/talents` also accepts `data` as-is and ignores `qualificationCriterias`. That call runs a paid search: it charges 1 API credit per profile returned, and `nbToFetch` defaults to 10.

The same prompt can yield slightly different filters, so store `data` if you need a stable search.

## Request body

**prompt** `string` *required*

Job description or natural-language brief, for example `"Data engineer in
    Paris with 5+ years of experience who knows Spark and has managed a team"`.
From 1 to 4,000 characters after leading and trailing whitespace is trimmed.
If the prompt cannot be turned into any usable filter, the request returns
`prompt_interpretation_failed`.

The body must be a JSON object with `prompt` only. Any other field, such as `nbToFetch`, is rejected with `400` `validation_error`.

## Limits

| Item | Limit |
| - | - |
| `prompt` | 1 to 4,000 characters after trimming. |
| Body fields | `prompt` only. Unknown fields are rejected. |
| `qualificationCriterias` | At most 10 entries, each at most 300 characters. Duplicates are removed, ignoring case. |
| `YEARS_OF_EXPERIENCE` | Returned as `"min-max"` with both bounds at most 100 and min ≤ max, so the search routes accept it. |
| Rate limits | Each call counts against the API key's request windows. See [Rate limits](/rate-limits.md). |

## Response

Successful responses carry two headers:

| Header | Value |
| - | - |
| `X-Api-Credits-Used` | Always `1` on success. |
| `X-Api-Credits-Remaining` | Your workspace balance right after this request. |

Error responses do not send these headers.

**success** `boolean`

Whether the request completed without errors.

**data** `object`

Present when `success` is `true`.

**data fields**

**filters** `object[]`

Filters in the same shape as [`POST /v1/search/talents`](/api-reference/search-talents). Some are optional (`isRequired: false`). Always contains at least one filter. Qualification criteria are never returned here; they are in `qualificationCriterias`.

**Filter object**

**filterType** `string`

One of the filter types accepted by `POST /v1/search/talents`, for example `JOB_TITLE`, `LOCATION`, `YEARS_OF_EXPERIENCE`, `SKILL`, or `KEYWORD`. See [accepted filter values](/api-reference/accepted-filter-values.md).

**value** `string`

The filter value, in the format the search routes accept for that `filterType`.

**isRequired** `boolean`

Whether the talent must match this filter.

**isExcluded** `boolean`

Whether talents matching this filter are excluded.

**isExactMatch** `boolean`

Whether the value must match exactly. Always `false` on `JOB_TITLE`.

**history** `string`

Present only on `JOB_TITLE` and `COMPANY_NAME`. One of `CURRENT`, `PAST`, or `CURRENT_AND_PAST`.

**radius** `number`

Present only on `LOCATION`, and only when a distance was extracted. Search radius in kilometers.

**qualificationCriterias** `string[]`

Criteria for the qualified-search judge, at most 10 entries, each at most 300 characters. Empty when the prompt produced none. Qualified search requires at least one; add one yourself before calling it.

**error** `object`

Error details, present when `success` is `false`.

**error fields**

**code** `string`

Machine-readable error code. One of: `validation_error`, `insufficient_api_credits`, `prompt_interpretation_failed`, `unsupported_location`, `missing_connected_linkedin_account`, `missing_api_key`, `invalid_api_key`, `expired_token`, `plan_upgrade_required`, `rate_limit_exceeded`, `internal_error`.

**message** `string`

Human-readable error description.

**debugTrackingCode** `string`

Unique tracking code for this request. Include it when contacting support.

**available** `number`

API credits available. Only present when `code` is `insufficient_api_credits`.

**required** `number`

API credits required, always `1`. Only present when `code` is `insufficient_api_credits`.

**issues** `object[]`

Zod validation details. Only present when `code` is `validation_error`.

**details** `object`

Present when `code` is `plan_upgrade_required` (billing remediation, see [Authentication](/authentication.md#error-responses)) or when `code` is `rate_limit_exceeded` on an API-key window.

**rate limit details fields**

**window** `string`

The time window that was exceeded. One of: `second`, `minute`, `hour`, `day`, `month`.

**limit** `number`

Maximum number of requests allowed in this window.

**current** `number`

Number of requests made in this window, including the rejected one.

## Credits

A successful call consumes **1 API credit**. The response sends `X-Api-Credits-Used: 1` and `X-Api-Credits-Remaining`. Billing labels the debit “API search inputs extraction”.

1. If the balance is `0`, the route returns `402` `insufficient_api_credits` and does not extract. `available` is `0` and `required` is `1`.
2. Otherwise 1 credit is reserved before the prompt is read.
3. If the prompt yields no usable filter, or the call fails at any step, the reservation is cancelled and no credit is consumed.
4. On success, the reserved credit is consumed.

See [Credits](/credits.md#extract-search-inputs).

## Errors

| Status | `error.code` | When |
| - | - | - |
| 400 | `validation_error` | Missing, empty, or too-long `prompt`, an unknown field, or a body that is not a JSON object. |
| 400 | `missing_connected_linkedin_account` | The prompt needs a connected LinkedIn account and none is connected. |
| 401 | `missing_api_key` | No API key was sent. |
| 401 | `invalid_api_key` | The API key or OAuth access token is not valid. |
| 401 | `expired_token` | The OAuth access token has expired. Re-authorize. |
| 402 | `insufficient_api_credits` | Balance is 0. `available` is `0` and `required` is `1`. |
| 402 | `plan_upgrade_required` | The workspace must subscribe or upgrade its plan before using the API. Search routes, including this one, do not require a subscription today. |
| 422 | `prompt_interpretation_failed` | The prompt produced no usable filter. No credit is consumed. |
| 422 | `unsupported_location` | A location in the prompt cannot be resolved. No credit is consumed. |
| 429 | `rate_limit_exceeded` | An API-key request window, or the per-IP limit on failed authentication, was exceeded. See [Rate limits](/rate-limits.md). |
| 500 | `internal_error` | The extraction failed. No credit is consumed. |

## Response examples

> **200 — Success**
>
> ```bash Request theme={null}
> curl -X POST https://app.kalent.ai/api/v1/search/talents/by-prompt/extraction \
>   -H "Content-Type: application/json" \
>   -H "x-api-key: YOUR_API_KEY" \
>   -d '{
>     "prompt": "Data engineer in Paris with 5+ years of experience who knows Spark and has managed a team"
>   }'
> ```
>
> ```text Response headers theme={null}
> X-Api-Credits-Used: 1
> X-Api-Credits-Remaining: 41
> ```
>
> ```json Response theme={null}
> {
>   "success": true,
>   "data": {
>     "filters": [
>       {
>         "filterType": "JOB_TITLE",
>         "value": "Data Engineer",
>         "isRequired": true,
>         "isExcluded": false,
>         "isExactMatch": false,
>         "history": "CURRENT"
>       },
>       {
>         "filterType": "LOCATION",
>         "value": "Paris",
>         "isRequired": true,
>         "isExcluded": false,
>         "isExactMatch": false
>       },
>       {
>         "filterType": "YEARS_OF_EXPERIENCE",
>         "value": "5-100",
>         "isRequired": false,
>         "isExcluded": false,
>         "isExactMatch": false
>       },
>       {
>         "filterType": "KEYWORD",
>         "value": "Spark",
>         "isRequired": false,
>         "isExcluded": false,
>         "isExactMatch": false
>       }
>     ],
>     "qualificationCriterias": ["Has managed a team"]
>   }
> }
> ```

> **400 — Validation error**
>
> Returned when the body does not match the schema. Here `nbToFetch` is not accepted by this route.
>
> ```bash Request theme={null}
> curl -X POST https://app.kalent.ai/api/v1/search/talents/by-prompt/extraction \
>   -H "Content-Type: application/json" \
>   -H "x-api-key: YOUR_API_KEY" \
>   -d '{
>     "prompt": "Data engineer in Paris",
>     "nbToFetch": 5
>   }'
> ```
>
> ```json Response theme={null}
> {
>   "success": false,
>   "error": {
>     "code": "validation_error",
>     "message": "Validation failed",
>     "debugTrackingCode": "V1StGXR8_Z5jdHi6B-myT",
>     "issues": [
>       {
>         "code": "unrecognized_keys",
>         "keys": ["nbToFetch"],
>         "path": [],
>         "message": "Unrecognized key(s) in object: 'nbToFetch'"
>       }
>     ]
>   }
> }
> ```
>
> An empty prompt returns the same envelope with this issue:
>
> ```json theme={null}
> {
>   "code": "too_small",
>   "minimum": 1,
>   "type": "string",
>   "inclusive": true,
>   "exact": false,
>   "message": "prompt must not be empty",
>   "path": ["prompt"]
> }
> ```

> **400 — Missing connected LinkedIn account**
>
> Returned when the prompt asks for LinkedIn connections and the workspace has no connected LinkedIn account. No credit is consumed.
>
> ```json Response theme={null}
> {
>   "success": false,
>   "error": {
>     "code": "missing_connected_linkedin_account",
>     "message": "No LinkedIn account is connected. Connect LinkedIn in your Kalent settings to filter results by LinkedIn connections.",
>     "debugTrackingCode": "V1StGXR8_Z5jdHi6B-myT"
>   }
> }
> ```

> **401 — Authentication error**
>
> Returned when the API key is missing or invalid, or when an OAuth access token has expired.
>
> ```bash Request theme={null}
> curl -X POST https://app.kalent.ai/api/v1/search/talents/by-prompt/extraction \
>   -H "Content-Type: application/json" \
>   -d '{
>     "prompt": "Data engineer in Paris"
>   }'
> ```
>
> ```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"
>   }
> }
> ```
>
> ```json Response (expired OAuth token) theme={null}
> {
>   "success": false,
>   "error": {
>     "code": "expired_token",
>     "message": "Access token has expired. Please re-authorize.",
>     "debugTrackingCode": "V1StGXR8_Z5jdHi6B-myT"
>   }
> }
> ```

> **402 — Insufficient API credits**
>
> Returned when the balance is 0. Nothing is extracted. Top up your credits and retry.
>
> ```json Response theme={null}
> {
>   "success": false,
>   "error": {
>     "code": "insufficient_api_credits",
>     "message": "Insufficient API credits: 0 available, 1 required.",
>     "available": 0,
>     "required": 1,
>     "debugTrackingCode": "V1StGXR8_Z5jdHi6B-myT"
>   }
> }
> ```

> **402 — Plan upgrade required**
>
> Returned by authentication when the workspace must subscribe or upgrade its plan. Search routes, including this one, do not require a subscription today.
>
> ```json Response theme={null}
> {
>   "success": false,
>   "error": {
>     "code": "plan_upgrade_required",
>     "message": "A Kalent subscription or plan upgrade is required to use the Kalent API. Please subscribe or upgrade your plan in Kalent billing: https://app.kalent.ai/settings/billing",
>     "debugTrackingCode": "V1StGXR8_Z5jdHi6B-myT",
>     "details": {
>       "code": "subscription_or_plan_upgrade_required",
>       "action": "subscribe_or_upgrade",
>       "capability": "use_kalent_api",
>       "billingUrl": "https://app.kalent.ai/settings/billing"
>     }
>   }
> }
> ```

> **422 — Prompt interpretation failed**
>
> Returned when the prompt could not be turned into any usable filter. Rephrase it with concrete criteria such as a job title, a location, or a skill. No credit is consumed.
>
> ```bash Request theme={null}
> curl -X POST https://app.kalent.ai/api/v1/search/talents/by-prompt/extraction \
>   -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 your prompt into any usable search filter. Please rephrase your query with more specific criteria.",
>     "debugTrackingCode": "V1StGXR8_Z5jdHi6B-myT"
>   }
> }
> ```

> **422 — Unsupported location**
>
> Returned when a location in the prompt cannot be resolved. Remove that location or rephrase it. Retrying the same value will not succeed. No credit is consumed.
>
> ```json Response theme={null}
> {
>   "success": false,
>   "error": {
>     "code": "unsupported_location",
>     "message": "Unsupported location: Singapore",
>     "debugTrackingCode": "V1StGXR8_Z5jdHi6B-myT"
>   }
> }
> ```

> **429 — Rate limit exceeded**
>
> Returned when an API-key request window is exceeded. A per-IP limit on failed authentication returns the same code with the message `Too many requests, please try again later` and no `details`. See [Rate limits](/rate-limits.md).
>
> ```json Response theme={null}
> {
>   "success": false,
>   "error": {
>     "code": "rate_limit_exceeded",
>     "message": "Rate limit exceeded: too many requests per minute",
>     "debugTrackingCode": "V1StGXR8_Z5jdHi6B-myT",
>     "details": {
>       "window": "minute",
>       "limit": 30,
>       "current": 31
>     }
>   }
> }
> ```

> **500 — Internal error**
>
> Returned when the extraction fails unexpectedly. No credit is consumed. Retry, and include `debugTrackingCode` if you contact support.
>
> ```json Response theme={null}
> {
>   "success": false,
>   "error": {
>     "code": "internal_error",
>     "message": "An error occurred during search inputs extraction",
>     "debugTrackingCode": "V1StGXR8_Z5jdHi6B-myT"
>   }
> }
> ```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.