# Bokföra en verifikation (/api/guider/bokfora-verifikation)

> Bokför en manuell verifikation via API:t – räkenskapsår, låst period, serie, konton och rättelser.

Den här guiden bokför en manuell verifikation, till exempel ett kortköp av kontorsmaterial. Alla belopp och nummer är påhittade exempel.

Du behöver en access token med scope `bookkeeping`. Den täcker räkenskapsår, serier, konton och verifikationer. Låst period kräver dessutom `settings`.

<Callout type="warn" title="En verifikation kan inte ändras">
`POST /3/vouchers` skapar en riktig verifikation i Klirrs bokföring. Det finns ingen `PUT` och ingen `DELETE`. Ett fel rättas med en ny verifikation.
</Callout>

<Steps>
<Step>
### Hitta räkenskapsåret [#hitta-räkenskapsåret]

`?financialyear=` är räkenskapsårets `Id`, inte ett årtal. Hämta id:t från `/3/financialyears`. Utelämnar du parametern gäller året som innehåller dagens datum.

<Tabs groupId="lang" persist items={['curl','TypeScript']}>
<Tab value="curl">
```bash
curl https://app.klirr.ai/api/v1/3/financialyears \
  -H "Authorization: Bearer <access_token>"
```
</Tab>
<Tab value="TypeScript">
```ts
const BASE = 'https://app.klirr.ai/api/v1';
const headers = {
  Authorization: 'Bearer <access_token>',
  'Content-Type': 'application/json',
};

const fy = await fetch(`${BASE}/3/financialyears`, { headers });
const { FinancialYears } = await fy.json();
const year = FinancialYears.find(
  (y: { FromDate: string; ToDate: string }) => y.FromDate <= '2026-10-14' && '2026-10-14' <= y.ToDate,
);
const financialYearId: number = year.Id; // t.ex. 3
```
</Tab>
</Tabs>

```json
{
  "FinancialYears": [
    { "@url": "https://app.klirr.ai/api/v1/3/financialyears/3", "Id": 3, "FromDate": "2026-01-01", "ToDate": "2026-12-31", "AccountChartType": "BAS 2013", "AccountingMethod": "ACCRUAL" }
  ],
  "MetaInformation": { "@TotalResources": 1, "@TotalPages": 1, "@CurrentPage": 1 }
}
```
</Step>

<Step>
### Kontrollera låst period [#kontrollera-låst-period]

Ett bokföringsdatum i en låst period ger `409`. Läs `EndDate` från `/3/settings/lockedperiod`. Fältet **utelämnas** när ingen period är låst.

<Tabs groupId="lang" persist items={['curl','TypeScript']}>
<Tab value="curl">
```bash
curl https://app.klirr.ai/api/v1/3/settings/lockedperiod \
  -H "Authorization: Bearer <access_token>"
```
</Tab>
<Tab value="TypeScript">
```ts
const lp = await fetch(`${BASE}/3/settings/lockedperiod`, { headers });
const { LockedPeriod } = await lp.json();
if (LockedPeriod.EndDate && '2026-10-14' <= LockedPeriod.EndDate) {
  throw new Error(`Perioden är låst till och med ${LockedPeriod.EndDate}`);
}
```
</Tab>
</Tabs>
</Step>

<Step>
### Välj serie och kontrollera kontona [#välj-serie-och-kontrollera-kontona]

Serien måste finnas och vara aktiv. Lista serierna med `/3/voucherseries`. Varje konto på raderna måste finnas och vara aktivt. Kontrollera med `GET /3/accounts/{Number}`.

<Tabs groupId="lang" persist items={['curl','TypeScript']}>
<Tab value="curl">
```bash
curl "https://app.klirr.ai/api/v1/3/voucherseries?financialyear=3" \
  -H "Authorization: Bearer <access_token>"

curl https://app.klirr.ai/api/v1/3/accounts/6110 \
  -H "Authorization: Bearer <access_token>"
```
</Tab>
<Tab value="TypeScript">
```ts
const vs = await fetch(`${BASE}/3/voucherseries?financialyear=${financialYearId}`, { headers });
const { VoucherSeriesCollection } = await vs.json();

for (const n of [6110, 2641, 1930]) {
  const acc = await fetch(`${BASE}/3/accounts/${n}`, { headers });
  const { Account } = await acc.json();
  if (!Account.Active) throw new Error(`Konto ${n} är inaktivt`);
}
```
</Tab>
</Tabs>

Listan heter `VoucherSeriesCollection`, inte `VoucherSeries`.
</Step>

<Step>
### Skapa verifikationen [#skapa-verifikationen]

`VoucherSeries`, `TransactionDate` och `Description` är obligatoriska. Summan av `Debit` måste vara exakt lika med summan av `Credit`, och en rad kan inte ha både debet och kredit. Skickar du `financialyear` måste `TransactionDate` ligga i det året.

<Tabs groupId="lang" persist items={['curl','TypeScript']}>
<Tab value="curl">
```bash
curl -X POST "https://app.klirr.ai/api/v1/3/vouchers?financialyear=3" \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{"Voucher":{"VoucherSeries":"A","TransactionDate":"2026-10-14","Description":"Kontorsmaterial, Pappershuset kvitto 8812","VoucherRows":[{"Account":6110,"Debit":1240},{"Account":2641,"Debit":310},{"Account":1930,"Credit":1550}]}}'
```
</Tab>
<Tab value="TypeScript">
```ts
const res = await fetch(`${BASE}/3/vouchers?financialyear=${financialYearId}`, {
  method: 'POST',
  headers,
  body: JSON.stringify({
    Voucher: {
      VoucherSeries: 'A',
      TransactionDate: '2026-10-14',
      Description: 'Kontorsmaterial, Pappershuset kvitto 8812',
      VoucherRows: [
        { Account: 6110, Debit: 1240 },
        { Account: 2641, Debit: 310 },
        { Account: 1930, Credit: 1550 },
      ],
    },
  }),
});
if (res.status !== 201) {
  const { ErrorInformation } = await res.json();
  throw new Error(ErrorInformation.Message);
}
const { Voucher } = await res.json();
```
</Tab>
</Tabs>

Svar (`201`, förkortat):

```json
{
  "Voucher": {
    "@url": "https://app.klirr.ai/api/v1/3/vouchers/A/58",
    "VoucherNumber": 58,
    "VoucherSeries": "A",
    "Year": 3,
    "TransactionDate": "2026-10-14",
    "Description": "Kontorsmaterial, Pappershuset kvitto 8812",
    "ReferenceType": "MANUAL",
    "VoucherRows": [
      { "Account": 6110, "Debit": 1240, "Credit": 0, "Description": "Förbrukningsmaterial", "Removed": false },
      { "Account": 2641, "Debit": 310, "Credit": 0, "Description": "Debiterad ingående moms", "Removed": false },
      { "Account": 1930, "Debit": 0, "Credit": 1550, "Description": "Företagskonto", "Removed": false }
    ]
  }
}
```
</Step>

<Step>
### Läs tillbaka verifikationen [#läs-tillbaka-verifikationen]

En verifikation identifieras av serie, nummer och räkenskapsår. Ange alltid `financialyear` när du hämtar den.

<Tabs groupId="lang" persist items={['curl','TypeScript']}>
<Tab value="curl">
```bash
curl "https://app.klirr.ai/api/v1/3/vouchers/A/58?financialyear=3" \
  -H "Authorization: Bearer <access_token>"
```
</Tab>
<Tab value="TypeScript">
```ts
const check = await fetch(
  `${BASE}/3/vouchers/${Voucher.VoucherSeries}/${Voucher.VoucherNumber}?financialyear=${financialYearId}`,
  { headers },
);
const { Voucher: stored } = await check.json();
```
</Tab>
</Tabs>
</Step>
</Steps>

## Rätta en verifikation [#rätta-en-verifikation]

Bokför en ny verifikation som vänder de felaktiga raderna, och därefter en med rätt belopp. Exemplet backar verifikation A 58:

```json
{
  "Voucher": {
    "VoucherSeries": "A",
    "TransactionDate": "2026-10-16",
    "Description": "Rättelse av A 58",
    "VoucherRows": [
      { "Account": 1930, "Debit": 1550 },
      { "Account": 6110, "Credit": 1240 },
      { "Account": 2641, "Credit": 310 }
    ]
  }
}
```

## Vanliga fel [#vanliga-fel]

| Status | Orsak |
|---|---|
| `400` | Obalanserad verifikation, konto som inte finns eller är inaktivt, okänd eller inaktiverad serie, eller ett datum utanför räkenskapsåret. |
| `404` | Okänt räkenskapsår eller verifikation som inte finns. |
| `409` | `TransactionDate` ligger i en låst period eller ett stängt räkenskapsår. |

Se [Verifikationer](/api/referens/vouchers) för alla fält och [Felkoder](/api/felkoder) för felformatet.
