> Reverse Contact API documentation. This is the Markdown copy of https://docs.reversecontact.com/endpoints/search-people-auto-completion-fields
> Every page is listed at https://docs.reversecontact.com/llms.txt, every endpoint with its credit cost and status at https://docs.reversecontact.com/catalog.json

# Search autocomplete for your product

> Build autocomplete into the search of your own product. Complete job titles, companies, schools, skills, languages, cities, regions, industries, countries and areas as your users type, for free, then send the value they pick to People search or its count endpoint.

- Endpoint: `POST https://api.reversecontact.com/v2/search/people/auto-completion-fields`
- Credits: Free.
- Answer: synchronous.
- Available in: REST API, TypeScript and Python SDKs.
- Last verified: 2026-11-10

## Introduction

Use this endpoint to build autocomplete into a search box of your own product. As your users type, it returns the values of a People search filter that complete what they typed, best first: job titles, company names, schools, skills, languages, cities, regions, industries, countries and areas. It returns values only, never a profile.

Send the `value` your user picks to the matching filter of [People search](https://docs.reversecontact.com/endpoints/search-people) or of its [free count](https://docs.reversecontact.com/endpoints/search-people-count), and show its `label`.

This endpoint **costs 0 credits** and has its own rate limit: 1,000 calls per minute per workspace, or 500 on the free trial, whatever the `field`. Its calls never use up your workspace's [requests per minute](https://docs.reversecontact.com/guides/rate-limits).

This endpoint was `POST /v2/search/people/auto-suggestion` until November 2026. The former path still answers the same request, with the values under `suggestions` and the object `search_auto_suggestions`. New integrations call the path of this page.

## Authorization

| Name     | Type   | Required | Description                                                                                         |
| -------- | ------ | -------- | --------------------------------------------------------------------------------------------------- |
| `apikey` | string | Yes      | Your API key from the developer dashboard. Pass it via `Authorization: Bearer YOUR_API_KEY` header. |

## Request body

| Name    | Type   | Required | Description                                                                      |
| ------- | ------ | -------- | -------------------------------------------------------------------------------- |
| `field` | string | Yes      | The filter to complete, one of the twelve values below                                                                        |
| `query` | string | Yes      | What has been typed so far, up to 100 characters, with a minimum of 1 to 3 that depends on the `field`. Case and accents are ignored |
| `limit` | number | No       | Maximum values returned, from 1 to 25. Defaults to 10                                                                         |

Each `field` completes one People search filter. Nine fields return the values found on profiles, most common first:

| `field`                | Send `value` in                                       | Example `value`      | Shortest `query` |
| ---------------------- | ----------------------------------------------------- | -------------------- | ---------------- |
| `positionTitle`        | `positionTitle`, `excludePositionTitle`               | `software engineer`  | 3 characters     |
| `currentPositionTitle` | `currentPositionTitle`, `excludeCurrentPositionTitle` | `head of marketing`  | 3 characters     |
| `companyName`          | `companyName`, `excludeCompanyName`                   | `microsoft`          | 3 characters     |
| `currentCompanyName`   | `currentCompanyName`                                  | `google`             | 3 characters     |
| `schoolName`           | [`schoolName`](https://docs.reversecontact.com/endpoints/search-people#schools) | `harvard university` | 2 characters     |
| `skills`               | [`skills`](https://docs.reversecontact.com/endpoints/search-people#skills)      | `python`             | 2 characters     |
| `languages`            | [`languages`](https://docs.reversecontact.com/endpoints/search-people#languages), `excludeLanguages` | `french` | 2 characters |
| `city`                 | `location.city`                                       | `sao paulo`          | 2 characters     |
| `region`               | `location.region`                                     | `california`         | 2 characters     |

Three fields return values from closed lists, from the first character:

| `field`       | Send `value` in                                                       | Example `value`        | Found by                                                                                |
| ------------- | --------------------------------------------------------------------- | ---------------------- | --------------------------------------------------------------------------------------- |
| `industry`    | `companyIndustry`, `currentCompanyIndustry`, `excludeCompanyIndustry` | `Software Development` | Its name, from the [industry values](https://docs.reversecontact.com/reference/industries)                        |
| `countryCode` | `location.countryCode`                                                | `FR`                   | Its ISO code (`FR`) or its English name (`France`)                                      |
| `area`        | `location.area`                                                       | `MC:DACH`              | Its id, its acronym (`DACH`) or its name, from the [area values](https://docs.reversecontact.com/reference/areas) |

Any other `field`, a `query` shorter than its field accepts or a `limit` out of range returns HTTP `422` with the code `VALIDATION_ERROR` and names the expected value: `"query" must be at least 3 characters for "positionTitle", received 2.`

The length of a `query` is counted as it is read: spaces around it are dropped, and so are brackets and commas. For `positionTitle`, `companyName` and `schoolName`, any run of punctuation counts as a single space.

### How values match

For the nine fields read from profiles, a value matches when it starts with `query`, spaces included: `machine l` returns the skill `machine learning`, `head of` returns the job titles `head of operations` and `head of marketing`, and `script` returns `scripting` but not `javascript`. The values held by the most profiles come first.

`positionTitle` and `companyName` read current and past positions, `currentPositionTitle` and `currentCompanyName` the current one only, like the filters of the same name.

`languages` returns the spellings found on profiles, in any language: `fr` returns `french`, `francais` and `frances`. In the `languages` filter, an English name also matches its other spellings, and another spelling matches itself only (see [Languages](https://docs.reversecontact.com/endpoints/search-people#languages)).

For `industry`, `countryCode` and `area`, the values come from closed lists and rank in this order:

1. A code typed whole: `fr` returns France first, `DACH` returns Germany, Austria & Switzerland. `UK`, `USA` and `UAE` also reach their country.
2. A name equal to the query.
3. A name that starts with the query: `fran` returns France.
4. A name whose words each start one typed word: `kingdom` returns United Kingdom, and `soft dev` returns Software Development before IT System Custom Software Development, since names that open on the first typed word come first.

Values of the same rank come in alphabetical order.

## Response structure

| Field     | Type    | Description                                      |
| --------- | ------- | ------------------------------------------------ |
| `success` | boolean | `true` if the request was processed successfully |
| `error`   | `null`  | Always `null` on success                         |

**data** (SearchAutoCompletion): Values that complete the query

| Field         | Type     | Description                                                   |
| ------------- | -------- | ------------------------------------------------------------- |
| `object`      | string   | Always `search_auto_completions`                              |
| `entity`      | string   | Always `person`                                               |
| `field`       | string   | The filter completed                                          |
| `completions` | object[] | The values, best first. Empty when no value matches the query |

**completions[]** (AutoCompletionValue): One value

| Field   | Type   | Description                                                                                       |
| ------- | ------ | ------------------------------------------------------------------------------------------------- |
| `value` | string | The value to send as it is in the filter: a job title, a company name, a school, a skill, a language, a city, a region, an industry, an ISO country code or an area id |
| `label` | string | The value to show: the country name (`France`), the area name, or the value itself for every other field |

The values read from profiles come in lowercase and without accents, as they are held for matching: `software engineer`, `sao paulo`. The values of `positionTitle`, `companyName` and `schoolName` also come without punctuation. These filters ignore case, so you can restyle a value for display and still send it.

## Build a search box

A few habits keep the box fast and within its limit:

- **Call from your server.** The call needs your API key, which must never reach a browser.
- **Wait for a pause in the typing.** Calling about 200 ms after the last key sends one request for a burst of keys.
- **Start each field at its shortest query.** Three characters for job titles and company names, two for schools, skills, languages, cities and regions, one for industries, countries and areas. A shorter `query` returns `422`, so do not send it.
- **Cancel the previous request** when a new one starts, so a late answer never replaces a newer one.
- **Keep the answers** for the session: the same query returns the same values.
- **Let people add what they typed** in the fields read from profiles. An empty list only means that no value starts this way, so a person can still search on their own wording.
- **Treat a `429` like an empty list.** The call returns `429` with the code `RATE_LIMIT_EXCEEDED` past its limit, and for the fields read from profiles also at times of very high demand, with a `Retry-After` header. Show no list, keep accepting what the person types, and try again on the next key.

## Code examples

**Code Examples**

```bash [cURL]
curl -X POST https://api.reversecontact.com/v2/search/people/auto-completion-fields \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "field": "countryCode",
    "query": "fr",
    "limit": 5
  }'
```
```typescript [TypeScript SDK]
import ReverseContact from "@reverse-contact/sdk";

const client = new ReverseContact({ apiKey: process.env.RC_API_KEY });

const result = await client.search.peopleAutoCompletionFields({
  field: "countryCode",
  query: "fr",
  limit: 5
});
console.log(result.data.completions?.map((completion) => `${completion.label} (${completion.value})`));
```
```python [Python SDK]
import os

from reversecontact import ReverseContact

with ReverseContact(api_key=os.environ["RC_API_KEY"]) as client:
    result = client.search.people_auto_completion_fields(
        field="countryCode",
        query="fr",
        limit=5,
    )
    if result.data is not None and result.data.completions is not None:
        print([(completion.label, completion.value) for completion in result.data.completions])
```

## Example response

**Example Response**

```json [200 - Success]
{
  "success": true,
  "data": {
    "object": "search_auto_completions",
    "entity": "person",
    "field": "countryCode",
    "completions": [
      { "value": "FR", "label": "France" },
      { "value": "GF", "label": "French Guiana" },
      { "value": "PF", "label": "French Polynesia" },
      { "value": "TF", "label": "French Southern Territories" },
      { "value": "MF", "label": "Saint Martin (French)" }
    ]
  },
  "error": null,
  "quotas": {
    "creditsConsumed": 0,
    "workspace": {
      "id": "ws_abc123",
      "credits": { "total": 10000, "used": 4521, "left": 5479 }
    }
  },
  "metadata": {
    "requestId": "5e0c03b5-38c7-46e2-9992-69478665e1b8",
    "executionTimeMs": 4
  }
}
```

A field read from profiles returns its values the same way, each with a `label` equal to its `value`: `{ "value": "python", "label": "python" }` for `skills`, `{ "value": "software engineer", "label": "software engineer" }` for `positionTitle`.
