# Artiklar (/api/referens/articles)

> Artikelregistret – lista, skapa, hämta, uppdatera och arkivera artiklar via /3/articles.

Artikelresursen speglar Fortnox `/3/articles`. Artikeln adresseras på sitt artikelnummer (`ArticleNumber`), och numret kan inte ändras när det väl är satt.

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

## Endpoints [#endpoints]

| Metod och sökväg | Beskrivning |
|---|---|
| <Endpoint method="GET" path="/api/v1/3/articles" /> | Lista artiklar (reducerad listform) |
| <Endpoint method="POST" path="/api/v1/3/articles" /> | Skapa en artikel. Svarar `201`. |
| <Endpoint method="GET" path="/api/v1/3/articles/{ArticleNumber}" /> | Hämta en artikel (fullständig form) |
| <Endpoint method="PUT" path="/api/v1/3/articles/{ArticleNumber}" /> | Uppdatera en artikel (partiellt) |
| <Endpoint method="DELETE" path="/api/v1/3/articles/{ArticleNumber}" /> | Arkivera en artikel. Svarar `204`. |

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

## Listparametrar [#listparametrar]

Utöver [paginering](/api/paginering) (`page`, `limit`, `offset`):

| Parameter | Värden | Beskrivning |
|---|---|---|
| `filter` | `active`, `inactive` | `active` utesluter arkiverade, `inactive` visar bara arkiverade. Utan filter (eller med okänt värde) returneras alla. |

Listrutten läser inga andra parametrar – `sortby`, `sortorder` och sökparametrar stöds inte på artiklar.

## Fält [#fält]

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

| Fält | Typ | Skrivskyddat | Beskrivning |
|---|---|---|---|
| `@url` | string | ja | Resursens URL. |
| `ArticleNumber` | string | efter skapande | Utelämnas det vid `POST` tilldelas ett nummer. Max 50 tecken: `A–Z`, siffror och `. _ - /`. |
| `Description` | string | nej | Benämning, max 1000 tecken. Kan inte vara tom eller nollas. |
| `Type` | `STOCK` \| `SERVICE` | nej | Standard `SERVICE`. Okänt värde tolkas som `SERVICE`. |
| `Active` | boolean | nej | `false` för arkiverad artikel. |
| `Expired` | boolean | nej | Alltid `!Active`. Kan skrivas som alias; vid konflikt vinner `Active`. |
| `SalesPrice` | number | nej | Försäljningspris exklusive moms. |
| `PurchasePrice` | number | nej | Inköpspris. |
| `VAT` | number | nej | Momssats: `25`, `12`, `6` eller `0`. Annan sats sätts till `25`. |
| `Unit` | string | nej | Enhet, returneras som den skickades. |
| `SalesAccount` | number | nej | Försäljningskonto. `0` när inget satts. |
| `EUAccount`, `EUVATAccount`, `ExportAccount`, `ConstructionAccount` | number | nej | Konton per momsbehandling. |
| `PurchaseAccount` | number | nej | Inköpskonto. |
| `EAN` | string | nej | Streckkod. |
| `Manufacturer` | string | nej | Tillverkare. |
| `ManufacturerArticleNumber` | string | nej | Tillverkarens artikelnummer. |
| `Note` | string | nej | Anteckning. |
| `SupplierNumber` | string | nej | Leverantörsnummer. Kopplas till en befintlig leverantör om den finns; annars sparas värdet som text. |
| `SupplierName` | string | nej | Leverantörsnamn, används för koppling om numret saknas. |
| `Housework` | boolean | nej | Omfattas av husavdrag. |
| `HouseworkType` | string | nej | Typ av husarbete. Okänt värde ignoreras. Sätts en typ blir `Housework` `true`. |
| `StockGoods` | boolean | ja | `true` när `Type` är `STOCK`. |
| `QuantityInStock`, `DisposableQuantity`, `ReservedQuantity`, `StockValue` | number | nej | Klirr har ingen lagerhantering. Värden du skickar bärs vidare oförändrade, annars `0`. |
| `WebshopArticle` | boolean | nej | Webbshopsartikel. |

Använd `"API_BLANK"` för att tömma `EAN`, `Manufacturer`, `ManufacturerArticleNumber`, `Note`, `Unit` och kontofälten. `API_BLANK` på `ArticleNumber`, `Description`, `Active` eller `Expired` ger `400`. Fält som Klirr inte modellerar sparas och returneras oförändrade.

### Listform [#listform]

`GET /3/articles` returnerar en reducerad rad: `@url`, `ArticleNumber`, `Description`, `EAN`, `Housework`, `SalesPrice`, `PurchasePrice`, `Unit`, `VAT`, `WebshopArticle`, `QuantityInStock`, `DisposableQuantity`, `ReservedQuantity`, `StockValue`. Talen är **strängar** i listformen.

## Skapa en artikel [#skapa-en-artikel]

<Tabs groupId="lang" persist items={['curl','TypeScript']}>
<Tab value="curl">
```bash
curl -X POST https://app.klirr.ai/api/v1/3/articles \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{"Article":{"ArticleNumber":"KONS-01","Description":"Konsulttimme","Type":"SERVICE","SalesPrice":950,"VAT":25,"Unit":"h"}}'
```
</Tab>
<Tab value="TypeScript">
```ts
const res = await fetch('https://app.klirr.ai/api/v1/3/articles', {
  method: 'POST',
  headers: {
    Authorization: 'Bearer <access_token>',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    Article: {
      ArticleNumber: 'KONS-01',
      Description: 'Konsulttimme',
      Type: 'SERVICE',
      SalesPrice: 950,
      VAT: 25,
      Unit: 'h',
    },
  }),
});
const { Article } = await res.json(); // 201 Created
```
</Tab>
</Tabs>

Svar (`201`):

```json
{
  "Article": {
    "@url": "https://app.klirr.ai/api/v1/3/articles/KONS-01",
    "ArticleNumber": "KONS-01",
    "Description": "Konsulttimme",
    "Type": "SERVICE",
    "Active": true,
    "Expired": false,
    "SalesPrice": 950,
    "PurchasePrice": 0,
    "VAT": 25,
    "Unit": "h",
    "SalesAccount": 0,
    "EUAccount": 0,
    "EUVATAccount": 0,
    "ExportAccount": 0,
    "ConstructionAccount": 0,
    "PurchaseAccount": 0,
    "EAN": "",
    "Manufacturer": "",
    "ManufacturerArticleNumber": "",
    "Note": "",
    "SupplierNumber": "",
    "SupplierName": "",
    "Housework": false,
    "HouseworkType": "",
    "StockGoods": false,
    "QuantityInStock": 0,
    "DisposableQuantity": 0,
    "ReservedQuantity": 0,
    "StockValue": 0,
    "WebshopArticle": false
  }
}
```

## Lista artiklar [#lista-artiklar]

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

```json
{
  "Articles": [
    {
      "@url": "https://app.klirr.ai/api/v1/3/articles/KONS-01",
      "ArticleNumber": "KONS-01",
      "Description": "Konsulttimme",
      "EAN": "",
      "Housework": false,
      "SalesPrice": "950",
      "PurchasePrice": "0",
      "Unit": "h",
      "VAT": "25",
      "WebshopArticle": false,
      "QuantityInStock": "0",
      "DisposableQuantity": "0",
      "ReservedQuantity": "0",
      "StockValue": "0"
    }
  ],
  "MetaInformation": { "@TotalResources": 1, "@TotalPages": 1, "@CurrentPage": 1 }
}
```

## Uppdatera en artikel [#uppdatera-en-artikel]

`PUT` ändrar bara de fält du skickar. Ändrar du `VAT` utan `Type` (eller tvärtom) räknas momskoden om mot artikelns sparade typ. 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/articles/KONS-01 \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{"Article":{"SalesPrice":1050}}'
```
</Tab>
<Tab value="TypeScript">
```ts
await fetch('https://app.klirr.ai/api/v1/3/articles/KONS-01', {
  method: 'PUT',
  headers: {
    Authorization: 'Bearer <access_token>',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ Article: { SalesPrice: 1050 } }),
});
```
</Tab>
</Tabs>

## Arkivera en artikel [#arkivera-en-artikel]

`DELETE` raderar inte artikeln. Den arkiveras, eftersom bokförda fakturarader kan referera till den. Svaret är `204`; artikeln försvinner ur `?filter=active` men finns kvar på sin URL med `Active: false`.

## Fel [#fel]

| Status | `Code` | När |
|---|---|---|
| 400 | 9000400 | Ogiltigt artikelnummer (tomt, över 50 tecken, otillåtna tecken), tom eller för lång `Description`, ogiltigt pris, `API_BLANK` på ett fält som inte kan nollas, otolkbart `Active`/`Expired`. |
| 404 | 9000404 | `Kan inte hitta artikeln`. |
| 409 | 9000409 | Artikelnumret används redan. |

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