# Anställda (/api/referens/employees)

> Personalregistret – lista, skapa, hämta och uppdatera anställda via /3/employees.

Personalresursen speglar Fortnox `/3/employees`. Den anställde adresseras på sitt anställningsnummer (`EmployeeId`), och numret kan inte ändras när det väl är satt.

**Scope:** `salary` · <Plan min="ai_pro" />

## Endpoints [#endpoints]

| Metod och sökväg | Beskrivning |
|---|---|
| <Endpoint method="GET" path="/api/v1/3/employees" /> | Lista anställda |
| <Endpoint method="POST" path="/api/v1/3/employees" /> | Skapa en anställd. Svarar **`200`**, inte `201`. |
| <Endpoint method="GET" path="/api/v1/3/employees/{EmployeeId}" /> | Hämta en anställd |
| <Endpoint method="PUT" path="/api/v1/3/employees/{EmployeeId}" /> | Uppdatera en anställd (partiellt) |

Bas-URL: `https://app.klirr.ai/api/v1`. Skrivningar kuverteras i `Employee`.

`POST` svarar `200` precis som Fortnox gör. Det är den enda skapande endpointen i API:t som inte svarar `201`.

Det finns ingen `DELETE`, varken hos Fortnox eller i Klirr. Att radera en anställd skulle radera bokförda lönespecifikationer. Avsluta i stället anställningen med `PUT` och `"Inactive": true`.

## Listparametrar [#listparametrar]

Utöver [paginering](/api/paginering) (`page`, `limit`, `offset`) och `sortorder` (`asc`/`desc`). Listan sorteras alltid på `EmployeeId`.

| Parameter | Värden | Beskrivning |
|---|---|---|
| `filter` | `active`, `inactive` | Utan filter returneras alla. Okänt värde ger `400`. |
| `employeeid` | text | Exakt anställningsnummer. Klirr-tillägg; finns inte hos Fortnox. |

`sortby` och `lastmodified` stöds inte och ger `400` i stället för ett tyst ofiltrerat svar.

## Personnummer maskeras alltid [#personnummer-maskeras-alltid]

`PersonalIdentityNumber` returneras **alltid maskerat** som `ÅÅÅÅMMDD-XXXX` (till exempel `19900101-XXXX`), eller `XXXXXXXX-XXXX` om numret inte har tolv siffror. API:t lämnar aldrig ut det fullständiga personnumret.

Skickar du tillbaka det maskerade värdet i en `PUT` ignoreras fältet, och det sparade personnumret lämnas oförändrat. Du kan alltså läsa en anställd, ändra ett fält och skicka tillbaka hela objektet utan att personnumret förstörs. Vill du ändra personnumret skickar du det fullständiga numret.

## Fält [#fält]

Fullständig form (`GET /3/employees/{EmployeeId}`, och svaret på `POST`/`PUT`).

| Fält | Typ | Skrivskyddat | Beskrivning |
|---|---|---|---|
| `EmployeeId` | string | efter skapande | Anställningsnummer. Utelämnas det vid `POST` tilldelas ett automatiskt. Kan inte ändras. |
| `PersonalIdentityNumber` | string | nej | Personnummer. **Maskerat i svaret**, se ovan. |
| `FirstName` | string | nej | **Obligatoriskt vid `POST`.** |
| `LastName` | string | nej | **Obligatoriskt vid `POST`.** |
| `FullName` | string | ja | Härlett ur för- och efternamn. Ignoreras vid skrivning. |
| `Email` | string | nej | E-post. |
| `Phone1` | string | nej | Telefon. |
| `EmploymentDate` | string | nej | Anställningsdatum, `YYYY-MM-DD`. |
| `MonthlySalary` | string | nej | Månadslön. **Sträng**, som hos Fortnox. Tal tas också emot. Ett värde som inte går att tolka ignoreras. |
| `HourlyPay` | string | nej | Timlön. Sträng, som `MonthlySalary`. |
| `Inactive` | boolean | nej | `true` för avslutad anställd. Observera att fältet är inverterat jämfört med `Active` på andra resurser. |
| `SalaryForm` | `MAN` \| `TIM` | nej | Månads- eller timlön. Okänt värde ignoreras. |
| `PersonelType` | `TJM` \| `ARB` | nej | Tjänsteman eller arbetare. Vid skrivning tas även `FORETAGSLEDARE` emot (bara om bolagsformen tillåter det, annars `400`). Svaret är alltid `TJM` eller `ARB`. Okänt värde ignoreras. |

`SalaryForm` och `PersonelType` har färre värden hos Fortnox än i Klirr: en företagsledare returneras som `TJM` och en deltidsanställd som `MAN`. Skickar du tillbaka samma värde i en `PUT` skrivs den mer precisa kategorin i Klirr inte över.

Övriga Fortnox-fält (adress, `BankAccountNo`, `TaxTable`, `TaxColumn`, `EmploymentForm`, semestersaldon, `DatedWages` m.fl.) modelleras inte av Klirr. De returneras alltid, med Fortnox nollvärde (`""`, `0`, `false` eller `[]`) eller med det värde du senast skickade, och slås vid `PUT` ihop med de sparade. Klirr använder dem inte i sin egen lönekörning. Till exempel härleds skattetabellen inte ur dem.

### Listform [#listform]

Personalresursen har ingen reducerad listform. `GET /3/employees` returnerar samma fält som den fullständiga formen plus `@url`. Omvänt saknar den fullständiga formen `@url`. Båda delarna stämmer med Fortnox.

## Skapa en anställd [#skapa-en-anställd]

<Tabs groupId="lang" persist items={['curl','TypeScript']}>
<Tab value="curl">
```bash
curl -X POST https://app.klirr.ai/api/v1/3/employees \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{"Employee":{"FirstName":"Anna","LastName":"Svensson","PersonalIdentityNumber":"<personnummer>","EmploymentDate":"2026-09-01","MonthlySalary":"32000","SalaryForm":"MAN","PersonelType":"TJM"}}'
```
</Tab>
<Tab value="TypeScript">
```ts
const res = await fetch('https://app.klirr.ai/api/v1/3/employees', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer <access_token>',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    Employee: {
      FirstName: 'Anna',
      LastName: 'Svensson',
      PersonalIdentityNumber: '<personnummer>',
      EmploymentDate: '2026-09-01',
      MonthlySalary: '32000',
      SalaryForm: 'MAN',
      PersonelType: 'TJM',
    },
  }),
});
const { Employee } = await res.json(); // 200 OK
```
</Tab>
</Tabs>

Svar (`200`), förkortat. De omodellerade Fortnox-fälten är utelämnade här:

```json
{
  "Employee": {
    "EmployeeId": "1",
    "PersonalIdentityNumber": "19900101-XXXX",
    "FirstName": "Anna",
    "LastName": "Svensson",
    "FullName": "Anna Svensson",
    "Email": "",
    "Phone1": "",
    "EmploymentDate": "2026-09-01",
    "MonthlySalary": "32000",
    "HourlyPay": "",
    "Inactive": false,
    "SalaryForm": "MAN",
    "PersonelType": "TJM",
    "EmploymentForm": "TV",
    "TaxTable": "",
    "TaxColumn": 0,
    "VacationDaysSaved": 0,
    "DatedWages": []
  }
}
```

## Lista anställda [#lista-anställda]

<Tabs groupId="lang" persist items={['curl','TypeScript']}>
<Tab value="curl">
```bash
curl "https://app.klirr.ai/api/v1/3/employees?filter=active" \
  -H "Authorization: Bearer <access_token>"
```
</Tab>
<Tab value="TypeScript">
```ts
const res = await fetch('https://app.klirr.ai/api/v1/3/employees?filter=active', {
  headers: { Authorization: 'Bearer <access_token>' },
});
const { Employees, MetaInformation } = await res.json();
```
</Tab>
</Tabs>

```json
{
  "Employees": [
    {
      "@url": "https://app.klirr.ai/api/v1/3/employees/1",
      "EmployeeId": "1",
      "PersonalIdentityNumber": "19900101-XXXX",
      "FirstName": "Anna",
      "LastName": "Svensson",
      "FullName": "Anna Svensson",
      "Inactive": false,
      "SalaryForm": "MAN",
      "PersonelType": "TJM"
    }
  ],
  "MetaInformation": { "@TotalResources": 1, "@TotalPages": 1, "@CurrentPage": 1 }
}
```

Raden ovan är förkortad. Varje rad innehåller alla fält i den fullständiga formen.

## Uppdatera en anställd [#uppdatera-en-anställd]

`PUT` ändrar bara de fält du skickar. Använd `"API_BLANK"` för att tömma ett fält. Det fungerar inte på `FirstName`, `LastName`, `Inactive` eller `PersonelType`, som ger `400`. Se [Fortnox-kompatibilitet](/api/fortnox-kompatibilitet).

<Tabs groupId="lang" persist items={['curl','TypeScript']}>
<Tab value="curl">
```bash
curl -X PUT https://app.klirr.ai/api/v1/3/employees/1 \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{"Employee":{"Inactive":true}}'
```
</Tab>
<Tab value="TypeScript">
```ts
await fetch('https://app.klirr.ai/api/v1/3/employees/1', {
  method: 'PUT',
  headers: {
    Authorization: 'Bearer <access_token>',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ Employee: { Inactive: true } }),
});
```
</Tab>
</Tabs>

## Fel [#fel]

| Status | `Code` | När |
|---|---|---|
| 400 | 9000400 | `FirstName` eller `LastName` saknas, okänt `filter`, `sortby` eller `lastmodified` skickat, `API_BLANK` på ett obligatoriskt fält, eller `FORETAGSLEDARE` när bolagsformen inte tillåter det. |
| 403 | 9000403 | Organisationens plan rymmer inte fler aktiva anställda. |
| 404 | 9000404 | `Kan inte hitta den anställde`. |
| 409 | 9000409 | Anställningsnumret används redan. |

Allmänna fel (401, 403, 429) beskrivs under [Felkoder](/api/felkoder).
