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

# Competence

> Skills, certificates and licences, and the assignments that give them to employees

A **competence** is something an employee can hold: a skill, a certificate, a licence, a completed course. Twine splits this into two entities, because the thing itself and the fact that someone holds it change independently.

<CardGroup cols={2}>
  <Card title="Competence" icon="award">
    The **catalogue entry** - "First Aid", "Forklift Licence", "German B2". One per organization, shared by everyone who holds it.
  </Card>

  <Card title="Competence Assignment" icon="user-check">
    The **link** between an employee and a catalogue entry, carrying the level, validity dates and who issued it.
  </Card>
</CardGroup>

Both use the [dated property model](/platform/data-model), so values can be tracked over time like any other Twine entity.

## Why two entities

Every serious HR system models it this way, and the reason is practical: renaming "First Aid" to "First Aid (Basic)" should not touch the two hundred employees who hold it, and one employee re-certifying should not touch the catalogue. Keeping them separate also means an organization can curate its catalogue independently of who currently holds what.

The consequence for configuration is that they are **two separate domains** with two separate domain mappings. Syncing the catalogue does not sync who holds what, and vice versa.

## Competence

The catalogue entry.

| Property             | Type   | Description                                                                                                                                                      |
| -------------------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`               | string | The competence name. Required. Together with `type` this is what Twine matches on when avoiding duplicates.                                                      |
| `type`               | string | Free-form category - `skill`, `certificate`, `licence`, `course`. Required. Target systems that use a fixed set of types expect a mapping onto their own values. |
| `code`               | string | A stable external code, where one exists - an ESCO identifier, an Open Badges id, or an internal code.                                                           |
| `description`        | string | Free text.                                                                                                                                                       |
| `source_external_id` | string | The id in the system the entry came from.                                                                                                                        |
| `custom_properties`  | object | Organization-defined extras.                                                                                                                                     |

<Note>
  **Level is not on the catalogue entry.** It belongs to the assignment - see below. Systems that model levels as separate catalogue entries ("English B1", "English B2") map cleanly anyway: each becomes its own competence, distinguished by `name` or `code`, with the assignment level left empty.
</Note>

## Competence Assignment

The link between an employee and a catalogue entry. An employee can hold the same competence more than once - a re-certification is a second assignment with a later `valid_from`, not an edit of the first.

| Property             | Type   | Description                                                                                                                                                        |
| -------------------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `level`              | string | Free-form proficiency - `Expert`, `3`, `B2`. Twine does not impose a scale; target systems with a fixed set of levels expect a mapping onto their own values.      |
| `valid_from`         | date   | When the assignment takes effect.                                                                                                                                  |
| `valid_to`           | date   | When it expires. Empty means it does not expire.                                                                                                                   |
| `issued_by`          | string | The issuing body or person.                                                                                                                                        |
| `notes`              | string | Free text.                                                                                                                                                         |
| `source_external_id` | string | The id in the system the assignment came from.                                                                                                                     |
| `custom_properties`  | object | Organization-defined extras. This is where a value a target system needs but Twine has no opinion about lives - see [Custom properties](#custom-properties) below. |

The employee and the competence themselves are not properties. They are relationships, resolved by Twine when data moves between systems.

### Custom properties

Some target systems need a value on the assignment that Twine has no general concept of - a reference to a document held in that system, for example. Rather than adding a field per system, put the value in an organization-defined custom property and map it onto the target's field. Custom properties are created in the property mapper the same way as for any other domain.

### Attaching a certificate

A common case is an assignment that should point at a certificate PDF stored in the target system. Twine does not link a file to an assignment for you - it moves the file and tells you what the target called it, and you supply that identifier yourself:

1. Upload the certificate with [`POST /v1/org/file-transfers`](/platform/other/file-transfers), naming the target system and the employee.
2. Poll the file transfer until its status is `delivered`, then read `remote_id` - the target system's identifier for the document.
3. Create the assignment with that value in the custom property mapped onto the target's document field.

Note the order. Several systems, Simployer One among them, accept a document reference only when the assignment is created; mapping it afterwards will not retrofit an assignment that already exists.

## How assignments resolve

An assignment refers to an employee and a catalogue entry. When Twine writes one to a target system, it needs that system's ids for both, which it takes from the [entity mappings](/platform/other/entity-mappings) built up when those domains sync.

That leads to the one rule worth knowing before configuring anything:

<Warning>
  **Both sides must already be mapped.** An assignment whose employee or competence has no mapping for the target system is skipped and [reported as an anomaly](/platform/other/anomalies) rather than guessed at. The anomaly resolves itself once the missing mapping appears.
</Warning>

This is why the domains are usually configured, and run, in a fixed order:

<Steps>
  <Step title="Employees">
    So every employee has a mapping in the target system.
  </Step>

  <Step title="Competences">
    So every catalogue entry has one too.
  </Step>

  <Step title="Competence assignments">
    Now both sides of every assignment can be resolved.
  </Step>
</Steps>

[Sync triggers](/platform/sync-triggers) can express this ordering directly: make the competence trigger a child of the employee trigger, and the assignment trigger a child of the competence one.

<Note>
  Not every integration needs three domain mappings. Some systems carry assignments inside the employee record itself, in which case the assignment domain does not apply. The integration page for each system states which shape it uses.
</Note>

## Matching existing data

When a target system already holds competences - most do, before Twine is introduced - the catalogue needs linking up so Twine writes to the existing entries instead of creating duplicates.

<Card title="Entity Matcher" icon="link" href="/backoffice/configuration/entity-matcher">
  Link the two catalogues by hand at onboarding. Competences are matched on name by default.
</Card>

Assignments are not matched this way. Once an employee and a competence are both mapped, the assignment between them is identified by that pair, so there is nothing for a human to link.

## Deletes

Competence syncing is **upsert-only** in both directions. A catalogue entry or an assignment removed in one system is not removed in the other - it is left alone. Removing an assignment from a target system is done there directly.
