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

# Person response shapes

> Exact full and compact person fields, nullability, hydration, and expansions.

`GET /people` returns a page envelope. Its `data` rows are full `Person` objects by default, or `CompactPerson` objects when `view=compact`. `GET /people/{slug}` always returns a fully hydrated `Person`. Company orbit rows use the same field names but hydrate only two positions and do not hydrate education, skills, languages, or certifications.

A missing value is normally represented as `null`; an empty array or object is distinct from `null`. Clients should ignore additional fields and should not infer employment from a display summary alone.

## CompactPerson

`view=compact` returns exactly the following fields for each search row:

| Field             | Type                        | Meaning                                                                                                             |
| ----------------- | --------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `slug`            | `string \| null`            | LinkedIn public identifier                                                                                          |
| `name`            | `string \| null`            | Compact alias for the full person's `full_name`                                                                     |
| `headline`        | `string \| null`            | Profile headline                                                                                                    |
| `linkedin_url`    | `string`                    | LinkedIn profile URL                                                                                                |
| `current`         | object `\| null`            | A display summary chosen from the first current position, or the first position when no current position is present |
| `current.company` | `string \| null`            | Company display name                                                                                                |
| `current.title`   | `string \| null`            | Position title                                                                                                      |
| `current.months`  | `number \| null`            | Position tenure in months                                                                                           |
| `match`           | object, optional            | Present only when the full match has a truthy company or company-month value                                        |
| `match.company`   | `string \| null \| omitted` | Company associated with the match                                                                                   |
| `match.months`    | `number \| omitted`         | Company-month match value                                                                                           |
| `open_to_work`    | `boolean \| null`           | LinkedIn-reported availability                                                                                      |
| `between_roles`   | `boolean`                   | Work history exists and no position is marked current                                                               |
| `exploring`       | `boolean`                   | FreshTalent's exploring assessment                                                                                  |
| `github_hireable` | `boolean \| null`           | GitHub's reported `hireable` value                                                                                  |

<Warning>`current` is a display summary, not proof of present employment. Use `between_roles` and the full person's `positions[].is_current` when that distinction matters. A compact row does not include the full position history, education, identity-enrichment objects, or explanation metadata.</Warning>

## Person

The full serializer emits these fields. `match` and `exploring_interpretation` are present as keys even when their value is an empty object or `null`.

| Field                      | Type              | Meaning                                                                                                                                             |
| -------------------------- | ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `slug`                     | `string \| null`  | LinkedIn public identifier                                                                                                                          |
| `full_name`                | `string \| null`  | Display name                                                                                                                                        |
| `headline`                 | `string \| null`  | Profile headline                                                                                                                                    |
| `linkedin_url`             | `string`          | Profile URL and stable join key                                                                                                                     |
| `profile_picture_url`      | `string \| null`  | Profile image URL                                                                                                                                   |
| `location`                 | object            | Always an object; `city`, `region`, and `country` are optional nullable strings when the source omits a property                                    |
| `is_open_to_work`          | `boolean \| null` | LinkedIn-reported flag                                                                                                                              |
| `is_between_roles`         | `boolean`         | Derived from recorded positions                                                                                                                     |
| `between_roles_since`      | `string \| null`  | Last role end, normally `YYYY-MM`, when between roles                                                                                               |
| `is_exploring`             | `boolean`         | Assessment flag; true only when a valid interpretation is available                                                                                 |
| `exploring_since`          | `string \| null`  | Earliest qualifying evidence date, normally `YYYY-MM-DD`                                                                                            |
| `exploring_reasons`        | object\[]         | Ordered reasons with `field`, `label`, nullable `before` and `after`, and `seen_at`                                                                 |
| `exploring_interpretation` | object `\| null`  | Validated explanation, or `null` when unavailable                                                                                                   |
| `connections_count`        | `number \| null`  | Source connection count                                                                                                                             |
| `followers_count`          | `number \| null`  | Source follower count                                                                                                                               |
| `last_enriched_at`         | `string \| null`  | Last enrichment timestamp                                                                                                                           |
| `dq_flags`                 | `string[]`        | Data-quality flags; ordinary search excludes these profiles                                                                                         |
| `github`                   | object `\| null`  | GitHub identity enrichment                                                                                                                          |
| `x`                        | object `\| null`  | X identity enrichment                                                                                                                               |
| `positions`                | Position\[]       | Recorded employment positions                                                                                                                       |
| `education`                | Education\[]      | Recorded education                                                                                                                                  |
| `skills`                   | `string[]`        | Source skills                                                                                                                                       |
| `languages`                | `string[]`        | Source spoken languages                                                                                                                             |
| `certifications`           | `Certification[]` | Certifications connected to the person; hydrated for `GET /people/{slug}` and certification-filtered people searches, otherwise `[]` on search rows |
| `match`                    | object            | Match, overlap, or recommendation metadata; may be `{}`                                                                                             |

### Position and education

A `Position` has nullable fields `company`, `company_url`, `title`, `started_at`, `ended_at`, `tenure_months`, `is_current`, and `role_family`. `tenure_months` is a number or `null`; `is_current` is a boolean or `null`. Dates retain the source precision, so do not invent a day when a value is only `YYYY` or `YYYY-MM`.

An `Education` has nullable string fields `school`, `degree`, `field`, `started_at`, `ended_at`, and `school_url`.

A `Certification` has a nonempty string `name` and nullable string fields `authority` and `issued_at`. Nameless records are omitted. `issued_at` preserves source precision (`YYYY` or `YYYY-MM`) and can be `null`. Certification search matches a literal, case-insensitive substring of `name` or `authority` through an actual `HAS_CERTIFICATION` relationship. The plural `certifications` request accepts up to 10 distinct terms and combines them with `certification_match=any` (default) or `all`; singular `certification` remains a compatibility alias. A record represents source data and does not verify current validity or expiration.

`GET /people/{slug}` hydrates all available positions after overlapping rows are collapsed, plus education, skills, languages, and certifications. People search hydrates at most two positions per row and leaves `education` empty. Search hydrates `skills` and `languages` only when their filters are used, and hydrates `certifications` only when a certification filter (`certification` or `certifications`) is used. Company orbit rows hydrate at most two positions and leave education, skills, languages, and certifications empty.

### Identity enrichment

When `github` is not `null`, it contains nullable fields `login`, `candidate_login`, `url`, `confidence`, `score`, `signals`, `hireable`, `blog`, `twitter`, and `reconciled_at`. `score` is a number or `null`; `hireable` is a boolean or `null`. A `candidate_login` is a candidate identity, not confirmation.

When `x` is not `null`, it contains nullable fields `handle`, `candidate_handle`, `url`, `confidence`, and `reconciled_at`. A candidate handle is not a confirmed identity.

### Match metadata

`match` can contain the following optional fields:

| Field             | Type             | Used for                                                                                                                   |
| ----------------- | ---------------- | -------------------------------------------------------------------------------------------------------------------------- |
| `company`         | `string \| null` | Company associated with a tenure match                                                                                     |
| `company_months`  | `number`         | Matched company tenure                                                                                                     |
| `role_months`     | `number`         | First matched role tenure                                                                                                  |
| `roles`           | object\[]        | Each item has `family` (`string`), `months` (`number`), `scope` (`company` or `anywhere`), and optional nullable `company` |
| `score`           | `number`         | Search or recommendation score                                                                                             |
| `overlap_company` | `string`         | Company overlap used for a coworker match                                                                                  |
| `overlap_months`  | `number`         | Overlap duration                                                                                                           |
| `overlap_from`    | `string`         | Overlap start, normally `YYYY-MM`                                                                                          |
| `overlap_to`      | `string \| null` | Overlap end; `null` means the overlap is current                                                                           |
| `title_during`    | `string \| null` | Coworker's title during the overlap                                                                                        |
| `reasons`         | `string[]`       | Similar-person recommendation reasons                                                                                      |

Coworker rows may use the overlap fields. Similar rows use `score` and `reasons`. Search rows can use company and role match fields. Do not assume any optional match key is present for every endpoint.

### Exploring explanation

Each `exploring_reasons` item has `field` of `headline`, `about`, or `role_description`; a string `label`; nullable `before` and `after`; and an ISO timestamp `seen_at`. Text is truncated by the serializer.

When `exploring_interpretation` is not `null`, it has:

* `model: string`
* `version: string`
* `segments: { text: string, evidence_indices: number[] }[]`
* `evidence: { field, label, before, after, seen_at, quote, side, source? }[]`

`side` is `before` or `after`; `source`, when present, is `snapshot`. Evidence indices point into the same `evidence` array. An assessment is not a statement that someone is actively seeking a job.

## Get-person expansions

`GET /people/{slug}?include=...` keeps the base `data` as a full `Person`. Unrequested top-level expansion keys are omitted.

* `include=coworkers` adds `coworkers: Person[]` and `stints: StintContext[]`.
* `include=similar` adds `similar: Person[]`.
* `include=coworkers,similar` adds all three arrays.

A `StintContext` has this structure (the nested `person` below is abbreviated; it uses the Person field shape):

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "stint": {
    "company": "Anduril",
    "title": "FDE",
    "started_at": "2025-01",
    "ended_at": null
  },
  "managers": [
    {
      "person": { "slug": "...", "match": { "overlap_months": 8 } },
      "title_during": "Director",
      "from": "2025-01",
      "to": null
    }
  ],
  "coworkers": [],
  "coworker_count": 0
}
```

`stint.company` is a string; the other stint fields are nullable strings. `managers` and `coworkers` contain full-shaped person rows with match metadata. `coworker_count` is the count before the preview list is truncated.

## Search envelope and pagination

A people search response is:

```json theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "data": [],
  "query": { "company": "palantir" },
  "meta": {
    "count": 0,
    "limit": 25,
    "offset": 0,
    "has_more": false,
    "total": 0,
    "total_capped": false
  }
}
```

`query` is the effective snake\_case filter object and excludes pagination. `meta.count` is the page length, `meta.limit` and `meta.offset` echo the request defaults or values, `meta.has_more` is true when the page is full (a following request can still be empty), and `meta.total` is `null` for an unfiltered browse. There is no cursor or next URL; request the next page by increasing `offset` by `limit`.

See [Search people](/api-reference/people/search) for parameter syntax and [Get person](/api-reference/people/get) for a fully hydrated dossier.
