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

# The Career Assignment object

> Who holds a career, at what level, and since when

<Info>
  **Quick Summary:** An assignment links a person to a career at a level. Assigning grants that level's learnings and attaches the career's skills; unassigning records career history first, so a person's past careers remain readable.
</Info>

## The assigned person

Returned by `GET /api/v1/careers/{id}/people`.

| Field                    | Type                          | Description                                                              |
| ------------------------ | ----------------------------- | ------------------------------------------------------------------------ |
| `id`                     | string                        | Opaque person id                                                         |
| `externalId`             | string \| null                | Your own identifier for this person — the Person resource's `externalId` |
| `firstName` / `lastName` | string \| null                | Name                                                                     |
| `email`                  | string \| null                | Email                                                                    |
| `level`                  | object \| null                | `{ id, name }` — the level this person holds within the career           |
| `assignedAt`             | string (ISO 8601 UTC) \| null | **Server-stamped** when the assignment was created. Read-only            |
| `initiationDate`         | string (ISO 8601 UTC) \| null | **Caller-supplied** date the person actually begins in the career        |

```json theme={null}
{
  "id": "4821",
  "externalId": "E-10422",
  "firstName": "Ada",
  "lastName": "Lovelace",
  "email": "ada@example.com",
  "level": { "id": "12", "name": "Level 2" },
  "assignedAt": "2026-03-11T08:22:10.000Z",
  "initiationDate": "2026-04-01T00:00:00.000Z"
}
```

<Note>
  The two dates have different owners. `assignedAt` is stamped by SkillsDB at the moment of the write and cannot be supplied; `initiationDate` is yours, and records when the person actually begins in the career.
</Note>

## The person's career

Returned by `GET /api/v1/people/{personId}/careers`. Previous (ended) assignments are included by default — pass `?includePrevious=false` to exclude them.

| Field            | Type                          | Description                                               |
| ---------------- | ----------------------------- | --------------------------------------------------------- |
| `id`             | string                        | Opaque career id                                          |
| `name`           | string \| null                | Career name                                               |
| `careerType`     | string \| null                | The family the career belongs to                          |
| `isPrevious`     | boolean                       | `true` for an ended assignment, `false` for a current one |
| `assignedAt`     | string (ISO 8601 UTC) \| null | When the assignment was created                           |
| `initiationDate` | string (ISO 8601 UTC) \| null | When the person began in the career                       |
| `skillsCount`    | number \| null                | Skills on the career                                      |

```json theme={null}
{
  "id": "318",
  "name": "Welder",
  "careerType": "Trades",
  "isPrevious": false,
  "assignedAt": "2026-03-11T08:22:10.000Z",
  "initiationDate": "2026-04-01T00:00:00.000Z",
  "skillsCount": 24
}
```

## The distribution

Returned by `GET /api/v1/careers/{id}/distribution`. Counted server-side — do not page through the assigned-people list to derive these numbers.

| Field    | Type  | Description                                |
| -------- | ----- | ------------------------------------------ |
| `levels` | array | Headcount per career level, in level order |
| `flags`  | array | Headcount per people-flag                  |

Each bucket is `{ id, label, count }`, where `id` is `null` for the catch-all bucket (for example *No Flag*).

```json theme={null}
{
  "levels": [{ "id": "12", "label": "Level 2", "count": 17 }],
  "flags": [{ "id": null, "label": "No Flag", "count": 17 }]
}
```

<Note>
  A credential bound to a manager sees only their span of control, so these counts reflect what the acting person is permitted to see — not necessarily the whole company.
</Note>

## Two rules that surprise integrations

**Assigning is never an update.** `POST /api/v1/careers/{id}/people` takes a list of people, each at their own level. Anyone already holding the career is skipped silently — no error, and no level change. If you need to move someone, use `PATCH /api/v1/careers/{id}/people/{personId}`; an integration that re-assigns expecting a correction will do nothing at all.

**Assigning fans out.** Beyond the assignment row, it grants every learning attached to the target level and attaches the career's skills to the person. One call against a hundred people is a large write, not a small one — budget it against your rate limit.

Both assign and unassign accept at most **500 people per call** — a larger array is rejected with a 400 [validation-error](/api-docs/errors/validation-error) before anything is written, so split bigger batches into chunks.
