Developers

Asstio API + MCP

Åtkomst till er Asstio-data för egna appar, dashboards, automatiseringar och AI-assistenter. REST för servrar och script, MCP för Claude, Cursor och andra AI-klienter. Varje anrop görs med en persons behörigheter, och v1 är stabil.

Asstio API + MCP

REST eller MCP — välj per use case

Samma underliggande data, samma versioneringskontrakt, samma authmodell. Skillnaden är vem som anropar.

REST

För servrar, script och webbappar

Versionerade endpoints under /api/v1/*, beskrivna i ett OpenAPI 3.1-dokument. Bygg dashboards, hämta data till Power BI, mata Slack-bottar eller kör nattliga jobb mot er Asstio-data med en API-nyckel.

# Hämta orderboken med en API-nyckel (asstio_…)
curl https://api.asstio.com/api/v1/sales-orders \
  -H "Authorization: Bearer $ASSTIO_KEY"
Versionerad (v1 är stabil) OpenAPI 3.1 API-nycklar: Läs eller Läs och skriv Cursor-paginering
MCP

För Claude, Cursor och AI-agenter

Samma data som verktyg en AI-assistent kan anropa, för att läsa och för att skriva. Implementerar Model Context Protocol över streamable-HTTP. Claude Desktop, Cline och Cursor sköter inloggningen själva, och verktygen körs med den inloggade användarens behörigheter.

// claude_desktop_config.json
{
  "mcpServers": {
    "asstio": {
      "url": "https://mcp.asstio.com/mcp"
    }
  }
}
Läs- och skrivverktyg OAuth via discovery (RFC 9728) 60 tool-calls/min/användare Streamable-HTTP

Från noll till första API-anropet — på 5 minuter

1. Skapa en API-nyckel

Gå till Inställningar → API-nycklar i Asstio. Ge nyckeln ett namn (t.ex. "Power BI"), välj Läs eller Läs och skriv och, om ni vill, ett utgångsdatum. Nyckeln visas bara en gång, så kopiera den direkt. Att skapa nycklar kräver behörigheten api_keys eller user_admin.

2. Lägg nyckeln i headern

Skicka nyckeln som Authorization: Bearer asstio_…. Den tas bara emot i headern, aldrig i URL:en. Förvara den på servern, inte i kod som körs i webbläsaren.

3. Ring en endpoint

Gör en GET mot /api/v1/customers?q=Acme. Bolaget följer med nyckeln, så ni skickar aldrig något tenant-id i URL eller header. Alla operationer går att prova med er egen nyckel i den interaktiva referensen.

Allt ni behöver för första anropet

GET /api/v1/customers?q=Acme
# Sök efter en kund
curl -G "$ASSTIO/api/v1/customers" \
  --data-urlencode "q=Acme" \
  -H "Authorization: Bearer $TOKEN"
// Response
{
  "items": [{
    "id": 412,
    "contactNumber": 10042,
    "name": "Acme Ltd",
    "orgno": "556677-8899",
    "openOrderCount": 3
  }],
  "nextCursor": null,
  "pageSizeApplied": 50,
  "truncated": false
}
POST /api/v1/sales-invoice-lines
# Vad sålde vi till Acme i april?
curl -X POST "$ASSTIO/api/v1/sales-invoice-lines" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "from": "2026-04-01", "to": "2026-04-30",
      "customerId": 412, "pageSize": 100 }'
// Response (1 av 23 rader)
{
  "productNumber": "WID-12",
  "quantity": 4.0,
  "sumExVat": 12000.00,
  "currencyIsoCode": "SEK"
}
MCP tools/call
// Be Claude i en chatt:
"Visa öppna leverans-rader till Kraft Group"

// Claude anropar:
{
  "method": "tools/call",
  "params": {
    "name": "list_open_order_lines",
    "arguments": { "customerId": 412 }
  }
}
// Claude svarar i naturligt språk
"Kraft Group har 6 order­rader öppna,
 totalt 18 enheter kvar att leverera —
 främst Widget WID-12 och Skruv M8."

Allt är en rad i Orders — diskriminerad av SystemName

Sälj­ordrar, sälj­fakturor, kreditfakturor och inköpsordrar är alla rader i samma tabell. Tre boolska flaggor på OrderStatus avgör vad som räknas som vad i rapporter.

Diskriminator: OrderStatusType.SystemName

SystemNameDokument
SALESORDERSäljorder (bokad, ej skickad)
SALESINVOICESäljfaktura (skickad/fakturerad)
SALESCREDITKreditfaktura (retur/återbetalning)
PURCHASEORDERInköpsorder mot leverantör

Flaggor: IsOrderIntake, IsSales, IsPurchase

  • IsOrderIntake = 1 — Räknas som orderintag. Inkluderar både SALESORDER (väntar leverans) och SALESINVOICE (redan skickad). Definierar orderboken.
  • IsSales = 1 — Räknas som omsättning. Exkluderar preview-/draft-/void-statusar.
  • IsPurchase = 1 — Aktiv inköpsorder (öppen eller pågående), inte stängd/avbruten.

Huvud-endpoints (/sales-orders, /sales-invoices, /purchase-orders) defaultar till den naturliga flaggan för sitt dokumenttyp, så out-of-the-box-siffror matchar Asstios BI. Override via statusKind-parametern eller pinna till en specifik statusId.

Ett urval av endpoints

Här är några av de vanligaste läsanropen och de tre för matchning av leverantörsfakturor. Klicka på en endpoint för att se request- och response-exempel. Hela v1, med parametrar, svar och felkoder för varje operation, finns i OpenAPI-dokumentet och i den interaktiva referensen. Båda går att läsa utan nyckel.

Base URL: https://api.asstio.com/api/v1/

GET /api/v1/sales-orders
list_sales_orders
Säljorderhuvuden — orderboken. Defaultar till statusKind=intake (statusar med IsOrderIntake=1). Filter på kund, status, datum, valuta, total. Hitta en kunds ordrar med email (adressen på ordern) eller shopOrderNumber (webbutikens ordernummer); då söks alla statusar. Med include=lines,fulfilment får varje order med sina rader och sin lager- och fraktstatus i samma svar, precis som /lines och /fulfilment ger dem, högst 25 ordrar per sida.

Request

curl -G "$ASSTIO/api/v1/sales-orders" \
  --data-urlencode "customerId=412" \
  --data-urlencode "orderDateFrom=2026-05-01" \
  -H "Authorization: Bearer $TOKEN"

Response item — SalesOrderDto

// 200 OK · X-Asstio-Api-Version: v1
{
  "id": 18743,
  "name": "Webshop order 2026-05",
  "customerId": 412,
  "customerName": "Acme Ltd",
  "customerOrgno": "556677-8899",
  "statusId": 31,
  "statusName": "Bekräftad",
  "dateOrder": "2026-05-12T00:00:00Z",
  "dateDelivery": "2026-05-25T00:00:00Z",
  "dateInvoice": null,
  "dateDue": null,
  "totalExVat": 18250.00,
  "totalVat": 4562.50,
  "totalIncVat": 22812.50,
  "openAmount": 22812.50,
  "isLate": false,
  "isFullyPaid": false,
  "hasShipmentDiscrepancy": false,
  "currencyIsoCode": "SEK"
}
GET /api/v1/sales-orders/{id}/fulfilment
get_sales_order_fulfilment
Var ordern är hos lagret och transportören, som lagret senast rapporterade: lagerstatus och varje kolli med transportör, kollinummer och spårningslänk. Bredvid finns /contact (orderns e-post, telefon och adresser) och /payment (betalstatus, kräver payment_manage).

Request

curl "$ASSTIO/api/v1/sales-orders/18743/fulfilment" \
  -H "Authorization: Bearer $TOKEN"

Response — SalesOrderFulfilmentDto

{
  "warehouseOrders": [{
    "orderNumber": "441147",
    "status": "shipped",
    "statusText": "Skickad",
    "shippedAt": "2026-09-30T14:02:00Z",
    "partial": false,
    "observedAt": "2026-09-30T14:05:12Z"
  }],
  "shipments": [{
    "carrier": "PostNord",
    "service": "MyPack Home",
    "parcelNumber": "00370…",
    "trackingUrl": "https://…",
    "returnParcelNumber": null
  }]
}
GET /api/v1/purchase-orders
list_purchase_orders
Inköpsordrar mot leverantörer. Defaultar till aktiva PO (IsPurchase=1). Filter på vendor, datum, valuta, mottaget värde och kvar-att-fakturera.

Request

curl -G "$ASSTIO/api/v1/purchase-orders" \
  --data-urlencode "vendorId=78" \
  -H "Authorization: Bearer $TOKEN"

Response item — PurchaseOrderDto

{
  "id": 92044,
  "purchaseNumber": 2026131,
  "vendorId": 78,
  "vendorName": "Northwind Components AB",
  "vendorOrgno": "112233-4455",
  "statusId": 64,
  "statusName": "Beställd",
  "dateOrder": "2026-05-02T00:00:00Z",
  "dateDelivery": "2026-05-30T00:00:00Z",
  "orderTotalExVat": 42500.00,
  "orderTotalIncVat": 53125.00,
  "receivedQtyPercent": null,
  "receivedValueExVat": 12700.00,
  "invoicedValueExVat": 0.00,
  "openToInvoiceExVat": 12700.00,
  "currencyIsoCode": "SEK"
}
GET /api/v1/sales-invoices
list_sales_invoices
Säljfakturahuvuden. Defaultar till intäkts­rader (IsSales=1). Sätt documentType=credit för kreditfakturor, both för kombinerat.

Request

curl -G "$ASSTIO/api/v1/sales-invoices" \
  --data-urlencode "customerId=412" \
  --data-urlencode "dueDateTo=2026-05-20" \
  -H "Authorization: Bearer $TOKEN"

Response item — SalesInvoiceDto

{
  "id": 88312,
  "invoiceNumber": 2026301,
  "customerId": 412,
  "customerName": "Acme Ltd",
  "customerOrgno": "556677-8899",
  "statusName": "Skickad",
  "dateInvoice": "2026-05-01T00:00:00Z",
  "dateDue": "2026-05-31T00:00:00Z",
  "dateOrder": "2026-04-28T00:00:00Z",
  "totalExVat": 12000.00,
  "totalVat": 3000.00,
  "totalIncVat": 15000.00,
  "openAmount": 15000.00,
  "paidAmount": 0.00,
  "isLate": false,
  "isFullyPaid": false,
  "currencyIsoCode": "SEK",
  "documentType": "invoice"
}
POST /api/v1/sales-invoice-lines
list_sales_invoice_lines
Sålda artikelrader — svar på "vad har vi sålt". POST eftersom filterytan är bred. Defaultar till lines från IsSales=1-fakturor.

Request body

{
  "from": "2026-01-01T00:00:00Z",
  "to": "2026-05-20T00:00:00Z",
  "customerId": 412,
  "productId": null,
  "statusId": null,
  "includeNonSales": false,
  "pageSize": 100
}

Response item — SalesInvoiceLineDto

{
  "invoiceId": 88312,
  "invoiceNumber": 2026301,
  "lineId": 410551,
  "productNumber": "WID-12",
  "description": "Widget, large",
  "quantity": 4.0,
  "qtyDelivered": 4.0,
  "price": 3000.00,
  "sumExVat": 12000.00,
  "sumIncVat": 15000.00,
  "currencyIsoCode": "SEK"
}
GET /api/v1/open-order-lines
list_open_order_lines
Säljorderrader med qtyLeftToDeliver > 0. Filter per kund, produkt eller lager. Sätt includeFullyDelivered=true för att även se färdigleveranser.

Request

curl -G "$ASSTIO/api/v1/open-order-lines" \
  --data-urlencode "customerId=412" \
  -H "Authorization: Bearer $TOKEN"

Response item — OpenOrderLineDto

{
  "orderId": 18743,
  "orderName": "Webshop order 2026-05",
  "lineId": 411099,
  "productNumber": "WID-12",
  "description": "Widget, large",
  "qtyOrdered": 10.0,
  "qtyDelivered": 4.0,
  "qtyLeftToDeliver": 6.0,
  "dateDelivery": "2026-05-25T00:00:00Z",
  "customerName": "Acme Ltd",
  "statusName": "Bekräftad"
}
GET /api/v1/warehouse-stock
get_warehouse_stock
Saldo per produkt per lagerplats. qtyDistributable färdig­räknad på servern. pageSize max 200.

Request

curl -G "$ASSTIO/api/v1/warehouse-stock" \
  --data-urlencode "productId=9921" \
  -H "Authorization: Bearer $TOKEN"

Response item — WarehouseStockRowDto

{
  "productId": 9921,
  "productNumber": "WID-12",
  "warehouseName": "Main",
  "locationName": "A-12-3",
  "qtyInStock": 47.0,
  "qtyIncoming": 20.0,
  "qtyOutgoing": 6.0,
  "qtyDistributable": 61.0
  // qtyInStock - qtyOutgoing + qtyIncoming
}
GET /api/v1/vendor-prices
list_product_vendor_prices
Leverantörspriser för en specifik produkt. productId är obligatorisk. Filter på supplierId och currencyCode.

Request

curl -G "$ASSTIO/api/v1/vendor-prices" \
  --data-urlencode "productId=9921" \
  -H "Authorization: Bearer $TOKEN"

Response item — VendorPriceDto

{
  "productId": 9921,
  "productNumber": "WID-12",
  "supplierId": 78,
  "supplierName": "Northwind Components AB",
  "supplierProductNumber": "NW-W-LRG",
  "price": 850.00,
  "currencyIsoCode": "SEK",
  "leadTimeDays": null,
  "validFrom": null,
  "validTo": null
}
GET /api/v1/products/find
Endast REST · MCP söker med search_products
Slå upp produkt på namn, artikelnummer eller beskrivning. q obligatorisk. Returnerar upp till limit kandidater (1–20, default 10) — array, inte PageResponse.

Request

curl -G "$ASSTIO/api/v1/products/find" \
  --data-urlencode "q=WID" \
  --data-urlencode "limit=10" \
  -H "Authorization: Bearer $TOKEN"

Response — array av ProductFindDto

[
  {
    "productId": 9921,
    "productNumber": "WID-12",
    "description": "Widget, large",
    "barcode": null,
    "isActive": true
  }
]
GET /api/v1/customers
list_customers
Sök eller lista kunder. Fritext mot id, namn eller orgnr. Sätt inactive=true för att inkludera inaktiva.

Request

curl -G "$ASSTIO/api/v1/customers" \
  --data-urlencode "q=Acme" \
  -H "Authorization: Bearer $TOKEN"

Response item — CustomerDto

{
  "id": 412,
  "contactNumber": 10042,
  "name": "Acme Ltd",
  "orgno": "556677-8899",
  "currencyIsoCode": null,
  "inactive": false,
  "openOrderCount": 3
}
GET /api/v1/customers/{customerId}
get_customer
Full kunddetalj: kreditlimit, förfallna ordrar, kreditstopp, betalnings-/leveransvillkor, prislista, vat-typ. 404 om kunden inte finns eller är i annan tenant.

Request

curl "$ASSTIO/api/v1/customers/412" \
  -H "Authorization: Bearer $TOKEN"

Response — CustomerDetailDto

{
  "id": 412,
  "contactNumber": 10042,
  "name": "Acme Ltd",
  "orgno": "556677-8899",
  "creditLimit": 250000.00,
  "overdueOrderSum": 4200.00,
  "creditStop": false,
  "paymentTermName": "30 dagar netto",
  "deliveryTermName": "Fritt vårt lager",
  "priceListName": "Standard",
  "orderCount": 84,
  "inactive": false
}
GET /api/v1/purchase-invoice-matches/{invoiceId}
suggest_purchase_invoice_matches
Top-5 kandidat-inleveransrader per fakturarad — med score, signaler (VendorSku, PriceExact, …), variances och isAutoEligible-flagga. Read-only, memory-cachad 30 sek per draft.

Request

curl "$ASSTIO/api/v1/purchase-invoice-matches/5012" \
  -H "Authorization: Bearer $TOKEN"

Response — PurchaseInvoiceMatchResponseDto

{
  "invoiceId": 5012,
  "tolerances": {
    "qtyPercent": 0.02,
    "pricePercent": 0.01,
    "dateWindowDays": 14,
    "autoEligibleScore": 70
  },
  "suggestions": [{
    "invoiceLineIndex": 0,
    "productNumber": "PROD-A",
    "quantity": 100,
    "candidates": [{
      "orderId": 9001,
      "orderItemId": 88012,
      "score": 100,
      "reasons": ["VendorSku", "QtyExact", "PriceExact"],
      "isAutoEligible": true
    }]
  }]
}
POST /api/v1/purchase-invoice-matches/{invoiceId}/confirm
Endast REST
Spara användarbekräftade (fakturarad → inleverans)-par på draften. Flera receipts kan knytas till samma invoiceLineIndex. Bokar inte verifikationen — det är fortfarande ett separat manuellt steg.

Request body

{
  "matches": [
    {
      "invoiceLineIndex": 0,
      "orderItemId": 88012,
      "invTransactionId": 130045
    }
  ]
}

Response

{
  "invoiceId": 5012
}
POST /api/v1/purchase-invoice-matches/{invoiceId}/match-whole-order
Endast REST
One-click-shortcut: knyt alla obokade inleveranser på vald PO till draften, fördelade per fakturarad av scorern (best-fit). Bra när AI-radextraktionen missade rader och fakturan mappar mot en PO.

Request body

{
  "orderId": 9001
}

Response

{
  "invoiceId": 5012
}

Exempel på integrationer

Realtids­dashboards i Power BI

Hämta säljorder, fakturarader och lagerstatus med en API-nyckel med behörigheten Läs, utan export eller mellanlager.

Claude som affärsanalytiker

"Visa mig de tre största kunderna med förfallna fakturor över 10 000 kr" — Claude anropar list_customers + list_sales_invoices och svarar direkt.

Slack-notifieringar

Pollera open-order-lines nattligt och posta i Slack om något ligger över 30 dagar utan delleverans.

Prisjämförelse mellan leverantörer

Kör vendor-prices för varje aktiv artikel — flagga när bästa pris ligger hos en leverantör ni inte använt på 6 månader.

AI-driven kundbrev

Be Cursor / Claude generera personliga uppföljnings­mejl baserat på kundens specifika orderhistorik från sales-invoice-lines.

Custom integrationer

Bygg en egen koppling mellan Asstio och ert CRM, BI-verktyg, e-postutskick eller supportverktyg.

En nyckel eller en inloggning, i samma header

Varje anrop bär en API-nyckel eller en inloggningstoken (JWT) i Authorization: Bearer-headern. Bolaget följer med nyckeln eller inloggningen, så ni skickar aldrig något tenant-id.

Webb-användare

Användare i Asstios egna webbgränssnitt har redan en token i sessionen. Er in-browser-kod kan läsa den och göra API-anrop direkt.

Backend, cron-jobb och Power BI

Skapa en API-nyckel under Inställningar → API-nycklar och skicka den som Authorization: Bearer asstio_…. Nyckeln agerar som en person, med exakt den personens behörigheter, och ändringar som görs med den loggas på personen. Nyckeln visas en gång, och Asstio sparar bara en hash av den. Byt nyckel genom att skapa en ny, flytta integrationen och återkalla den gamla.

AI-assistenter via MCP

Claude Desktop, Cline och liknande loggar in själva via discovery-endpointen (RFC 9728) på https://mcp.asstio.com. Klienter utan OAuth kan få en inloggningstoken inklistrad i sin konfiguration. API-nycklar fungerar inte mot MCP-servern. Skrivande verktyg körs med användarens behörigheter, och Asstio lägger inget eget bekräftelsesteg ovanpå, så det är er MCP-klient som avgör om ni tillfrågas först.

Läs, skriv och vem som får skapa

En nyckel är Läs eller Läs och skriv, och valet går inte att ändra efteråt. En nyckel med Läs får 403 på anrop som skriver. Nycklar som agerar som er själva kräver behörigheten api_keys. Den som har user_admin kan låta en nyckel agera som en annan inloggningsanvändare, t.ex. en egen "Power BI"-användare, och ser och återkallar alla bolagets nycklar. En återkallad eller utgången nyckel, eller en nyckel vars person har inaktiverats, slutar fungera inom 60 sekunder.

v1 · STABILT

Versions­kontrakt

Inuti v1 gör vi bara additiva ändringar — nya endpoints, nya valbara fält, nya query-parametrar. Existerande fältnamn, typer och default-beteenden ändras inte. Ett undantag görs bara med avsikt och står i ändringsloggen i /llms-api.txt. Hittills finns ett: i september 2026 ändrades skrivanropen för butikens filterinställningar, som bara Asstios MCP-server anropar. Breaking changes landar i v2 på en separat URL-prefix. v1 fortsätter köra tills sista integratorn flyttat över.

Varje response under /api/v1/* bär headern X-Asstio-Api-Version: v1 — pin emot den om ni vill ha försvar mot oavsiktliga uppgraderingar.

ERRORS

ErrorEnvelope på de flesta fel

De flesta fel returnerar samma struktur — code, message och valfritt traceId. 401 = saknad eller ogiltig token eller nyckel, och för operationerna i OpenAPI-dokumentet alltid med den här strukturen. 403 = giltig token men behörighet saknas, eller en nyckel med Läs på ett skrivande anrop. 404 = id:t finns inte hos bolaget. 429 = MCP:s gräns på 60 anrop per minut är nådd, eller en API-nyckel kunde inte kontrolleras för stunden; försök igen efter Retry-After. 500 = serverfel, utan garanterad body. Några operationer har egna felformat, och OpenAPI-dokumentet anger vilka.

{
  "code": "not_found",
  "message": "Customer 99999 not found",
  "traceId": null
}
Få access

Redo att börja bygga?

Skapa en nyckel under Inställningar → API-nycklar och börja i den interaktiva referensen. Säg gärna till vad ni vill bygga, så pekar vi mot rätt endpoints.

Kontakta oss Boka demo →