> ## 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 Certification object

> The company's certification library — what a certification is, not who holds it

<Info>
  **Quick Summary:** A certification is a library entry: a name, a description, the type it is grouped under, and the authority that issues it. Full management over the API. What a *person* holds — their record, its approval workflow, evidence and expiry — is the separate [Person Certification](/api-docs/resources/person-certification) resource.
</Info>

## Attributes

| Field                     | Type                  | Description                                                                                                                 |
| ------------------------- | --------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `id`                      | string                | Opaque certification id                                                                                                     |
| `name`                    | string                | Name                                                                                                                        |
| `description`             | string \| null        | Description                                                                                                                 |
| `type`                    | object \| null        | `{ id, name }` of the [certification type](/api-docs/resources/certification-type) it is grouped under; `null` when untyped |
| `issuingAuthorityName`    | string \| null        | The organisation or body that issues it                                                                                     |
| `issuingAuthorityUrl`     | string \| null        | The issuing authority's website                                                                                             |
| `labels`                  | array                 | `{ id, name }` of every label attached, in label order. Labels are attached and detached through the label endpoints        |
| `holderCount`             | integer               | People holding the certification — directly, or through a career that includes it                                           |
| `holdersWithFileCount`    | integer               | Holders who have attached at least one file as evidence                                                                     |
| `createdAt` / `updatedAt` | string (ISO 8601 UTC) | Timestamps; `updatedAt` may be `null`                                                                                       |

```json theme={null}
{
  "id": "87",
  "name": "Forklift Operator Licence",
  "description": "Required for warehouse floor access.",
  "type": { "id": "4", "name": "Regulatory" },
  "issuingAuthorityName": "National Safety Council",
  "issuingAuthorityUrl": "https://www.nsc.org",
  "labels": [{ "id": "12", "name": "Safety" }],
  "holderCount": 14,
  "holdersWithFileCount": 9,
  "createdAt": "2026-01-12T08:30:00.000Z",
  "updatedAt": null
}
```

A certification has **no expiry of its own**. Expiry belongs to a person's record of it — two people can hold the same certification with different expiry dates.

## Operations

| Operation              | Method and path                      | Requires scope         |
| ---------------------- | ------------------------------------ | ---------------------- |
| List certifications    | `GET /api/v1/certifications`         | `certifications:read`  |
| Get a certification    | `GET /api/v1/certifications/{id}`    | `certifications:read`  |
| Create a certification | `POST /api/v1/certifications`        | `certifications:write` |
| Update a certification | `PATCH /api/v1/certifications/{id}`  | `certifications:write` |
| Delete a certification | `DELETE /api/v1/certifications/{id}` | `certifications:write` |

### Listing

Filterable by `name`, `issuingAuthorityName` and `type` (the type's name); sortable by `name` and `createdAt`. See [Filtering](/api-docs/rest/filtering) and [Sorting](/api-docs/rest/sorting).

```http theme={null}
GET /api/v1/certifications?filter[type][eq]=Regulatory&sort=name
```

### Creating and updating

`name` is required on create; `description`, `certificationTypeId`, `issuingAuthorityName` and `issuingAuthorityUrl` are optional. A `certificationTypeId` must be one of the company's types — an unknown id is a field-level [validation-error](/api-docs/errors/validation-error), never a silent dangling reference.

On `PATCH`, an omitted field is left untouched and an explicit `null` **clears** `description`, `certificationTypeId`, `issuingAuthorityName` or `issuingAuthorityUrl`. Labels are not part of this body: attach and detach them through the label endpoints.

### Deleting

Deletion is guarded. If anyone holds the certification, or any career includes it, the call answers [409 conflict](/api-docs/errors/conflict) with the counts:

```json theme={null}
{
  "type": "https://help.skillsdb.com/api-docs/errors/conflict",
  "title": "Conflict",
  "status": 409,
  "detail": "People hold this certification or careers include it. Retry with ?confirm=true to delete it anyway (holders keep their records as history; career links are removed).",
  "confirmRequired": true,
  "dependencies": { "people": 14, "careers": 2 }
}
```

Retry with `?confirm=true` to proceed: the certification is soft-deleted and disappears from the library and from every career; holders' records stay as history. An unheld, unlinked certification deletes immediately with `204`.

## Permissions

Every call is the intersection of the key's scopes and what the **acting person** may do in the app. Reads, creates and updates are broadly permitted; **delete is restricted to global administrators**, and a key acting as a person who cannot delete receives [insufficient-permissions](/api-docs/errors/insufficient-permissions). Two roles hold no certification permissions at all in the app today, so a key bound to a person in one of them is refused on every certification endpoint with the same problem type — bind the key to a person who can manage certifications.

## Related errors

* [not-found](/api-docs/errors/not-found) — the id does not exist in your company (another company's certification answers the same 404)
* [validation-error](/api-docs/errors/validation-error) — a missing name, an over-long field, or an unknown `certificationTypeId`
* [conflict](/api-docs/errors/conflict) — the guarded delete above
* [insufficient-scope](/api-docs/errors/insufficient-scope) / [insufficient-permissions](/api-docs/errors/insufficient-permissions) — see Permissions
