> ## 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 Person Skill object

> One row per person per skill — the self and manager grades on it, the resolved benchmark, the flags, and where the skill came from

<Info>
  **Quick Summary:** A person skill is a skill on a person's profile. It carries the person's self grade and the manager's grade (each with years of experience), a resolved benchmark, the not-applicable and focus flags, and its origin — attached directly, derived from one or more careers, or both. A grade is a value *on* the record; the record itself is not a score. Every grade and benchmark is a resolved rung (`{ id, grade, label }`), never a bare integer.
</Info>

## Attributes

| Field                                             | Type                                                   | Description                                                                                                                        |
| ------------------------------------------------- | ------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| `id`                                              | string                                                 | The skill id                                                                                                                       |
| `name` / `description` / `isCertification`        |                                                        | The skill                                                                                                                          |
| `selfGrade`                                       | rung \| null                                           | The person's own grade                                                                                                             |
| `selfYearsOfExperience`                           | number \| null                                         | Self-reported                                                                                                                      |
| `managerGrade`                                    | rung \| null                                           | The manager's grade                                                                                                                |
| `managerYearsOfExperience`                        | number \| null                                         | Manager-reported                                                                                                                   |
| `managerGradeUpdatedAt` / `managerGradeUpdatedBy` | string \| null, `{ id, name }` \| null                 | When the manager grade last changed and who changed it                                                                             |
| `benchmark.effective` / `benchmark.source`        | rung \| null, `manager` \| `level` \| `career` \| null | The single resolved benchmark and which value won                                                                                  |
| `benchmark.manager`                               | rung \| null                                           | A manager-set benchmark for this person on this skill                                                                              |
| `benchmark.careers[]`                             |                                                        | Per career deriving the skill: `career`, `level`, `effective`, `effectiveSource`, the career, its skill and the assignment's level |
| `notApplicable`                                   | boolean                                                | Excluded from the profile; setting it clears the manager grade                                                                     |
| `focus.employee` / `focus.manager`                | boolean                                                | Two independent development-focus flags                                                                                            |
| `origin.direct`                                   | boolean                                                | Attached to the profile in its own right                                                                                           |
| `origin.careers[]`                                | `{ careerId, careerName, careerSkillId }`              | The careers deriving the skill, and the career skill each derives through                                                          |

**The benchmark rule is the app's, written down:** most specific wins — the manager benchmark, then the assignment level's benchmark (whenever the assignment has a level, even if that level sets none), then the career's benchmark. Across several careers the highest career-derived effective value is published as `benchmark.effective`; the contributing values are all present so a caller can see which one won.

```json theme={null}
{
  "id": "77",
  "name": "Forklift Operation",
  "description": null,
  "isCertification": false,
  "selfGrade": { "id": "2", "grade": 2, "label": "Competent" },
  "selfYearsOfExperience": 3,
  "managerGrade": { "id": "3", "grade": 3, "label": "Proficient" },
  "managerYearsOfExperience": 4,
  "managerGradeUpdatedAt": "2026-02-01T10:00:00.000Z",
  "managerGradeUpdatedBy": { "id": "1041", "name": "Sam Ortega" },
  "benchmark": {
    "effective": { "id": "3", "grade": 3, "label": "Proficient" },
    "source": "career",
    "manager": null,
    "careers": [
      { "careerId": "31", "careerName": "Warehouse Operator", "careerSkillId": "512", "levelId": null, "levelName": null,
        "career": { "id": "3", "grade": 3, "label": "Proficient" }, "level": null,
        "effective": { "id": "3", "grade": 3, "label": "Proficient" }, "effectiveSource": "career" }
    ]
  },
  "notApplicable": false,
  "focus": { "employee": false, "manager": true },
  "origin": { "direct": true, "careers": [{ "careerId": "31", "careerName": "Warehouse Operator", "careerSkillId": "512" }] }
}
```

## Operations

### A person's skills

| Operation                                            | Method and path                                                | Requires scope     |
| ---------------------------------------------------- | -------------------------------------------------------------- | ------------------ |
| List a person's skills                               | `GET /api/v1/people/{personId}/skills`                         | `skills:read`      |
| Get one of a person's skills                         | `GET /api/v1/people/{personId}/skills/{skillId}`               | `skills:read`      |
| List person skills for a population                  | `GET /api/v1/person-skills?scope=company\|team\|org&subject=…` | `proficiency:read` |
| Skill matrix — people with a skill, and their grades | `GET /api/v1/skills/{id}/matrix`                               | `proficiency:read` |

`personId` is an email or an opaque id. The list returns every skill on the profile — attached directly or derived from a career — with the full object above. The population read is one operation over the app's three reads: `scope=company` needs an administrator-level acting person; `scope=team` and `scope=org` read the team or organisation branch of the manager named by `subject`, who must be the acting person or within their span. Rows are one per person per skill (per career when graded through one) and are filterable by `skillName`, `skillId`, `firstName`, `lastName`.

### Grading

| Operation                      | Method and path                                                  | Requires scope      |
| ------------------------------ | ---------------------------------------------------------------- | ------------------- |
| Set the self grade             | `PUT /api/v1/people/{personId}/skills/{skillId}/self-grade`      | `proficiency:write` |
| Set the manager grade          | `PUT /api/v1/people/{personId}/skills/{skillId}/manager-grade`   | `proficiency:write` |
| Grade a person across a career | `POST /api/v1/people/{personId}/careers/{careerId}/grades`       | `proficiency:write` |
| Set a per-person benchmark     | `PUT /api/v1/people/{personId}/skills/{skillId}/benchmark`       | `proficiency:write` |
| Mark a skill not applicable    | `PUT /api/v1/people/{personId}/skills/{skillId}/not-applicable`  | `proficiency:write` |
| Flag a skill as a focus        | `PUT /api/v1/people/{personId}/skills/{skillId}/focus`           | `proficiency:write` |
| Remove a skill from a person   | `DELETE /api/v1/people/{personId}/skills/{skillId}?attachment=…` | `proficiency:write` |

Grades take `{ "gradeId": "3", "yearsOfExperience": 4, "comment": "…" }`; `gradeId` must be a rung of the company grading scale (a field-level [validation error](/api-docs/errors/validation-error) otherwise). **Only the person may set their self grade**; the manager grade needs the acting person to manage the subject or to be an administrator.

**Grade across a career** takes `{ "grades": [{ "skillId", "managerGradeId"?, "managerYearsOfExperience"?, "selfGradeId"?, "selfYearsOfExperience"? }] }` and applies to skills the career requires for that person; any other skill is [422 unprocessable](/api-docs/errors/unprocessable).

**Grading attaches the skill directly as well**, as the app does: after a grade, `origin.direct` is true even for a skill that arrived through a career, and the career derivation is kept alongside it.

**Benchmark** takes `{ "gradeId": "4" }` or `{ "gradeId": null }` to clear — never a zero. **Not applicable** takes `{ "notApplicable": true }` and **clears the person's manager grade**: this is not a display flag, it discards data. **Focus** takes `{ "employee": true }` (the person only) and/or `{ "manager": true }`; clearing the manager flag also clears the employee flag, as in the app.

**Remove** must say which attachment goes: `attachment=direct` (the default) drops the skill added in its own right — a 404 when the skill is only career-derived; `attachment=career&careerId=31` clears the grade held through one career — the derivation itself stays for as long as the career requires the skill; `attachment=all` does both. To take a career-required skill off a profile, remove the career assignment (see [Career](/api-docs/resources/career-assignment)) or the skill from the career.

### Grade reporting

| Operation                     | Method and path                                          | Requires scope     |
| ----------------------------- | -------------------------------------------------------- | ------------------ |
| Skill statistics for a person | `GET /api/v1/people/{personId}/skill-statistics`         | `proficiency:read` |
| Scorecard summary             | `GET /api/v1/people/{personId}/scorecard?assessmentId=…` | `proficiency:read` |
| Grade trends for a career     | `GET /api/v1/careers/{id}/grade-trends?perSkill=true`    | `proficiency:read` |

**Statistics** answers `{ attachedSkills, benchmarksMet, variances, skillGaps }`. **Scorecard** is the app's named surface and is **assessment-scoped**: `assessmentId` names the cycle the grades are rolled up within (required; a person who is not a participant of that cycle is a 404). The roll-up is per career assignment. Note that the scorecard's `totalBenchmarkMet` is measured against the **career** benchmark only, as in the app — it ignores the level and manager benchmarks that the person skill's `benchmark.effective` resolves. **Trends** returns per-period averages of the self and manager grades of the people on the career.

## Permissions

Any person who can see a person in the app can read their skills, statistics and scorecard here. Grading follows the app: a person grades themself; their manager (or an administrator) sets the manager grade, benchmark, not-applicable and manager-focus flags and removes skills. A key acting as someone outside those relationships receives [insufficient-permissions](/api-docs/errors/insufficient-permissions) or, for a person outside its span, [not-found](/api-docs/errors/not-found).

## Excluded

What a career requires — benchmarks, per-level activation and required status — belongs to [Career](/api-docs/resources/career). The skill itself belongs to [Skill](/api-docs/resources/skill). Training records belong to [Training](/api-docs/resources/training); grades set through an assessment cycle belong to [Assessment](/api-docs/resources/assessment) and are readable here once set. Skill flags on a person belong to [Flag](/api-docs/resources/flag). CSV grade import is an in-app path.

## Related errors

* [not-found](/api-docs/errors/not-found) — the person is not in your company or outside your span; the skill is not on their profile; the attachment asked for does not exist
* [validation-error](/api-docs/errors/validation-error) — an unknown rung, a missing `subject` or `careerId`, an unknown `scope` or `attachment`
* [unprocessable](/api-docs/errors/unprocessable) — grading a skill that is not part of the career
* [insufficient-permissions](/api-docs/errors/insufficient-permissions) — setting another person's self grade or employee focus; a non-administrator asking for the company-wide population
