Hoppa till innehållet
CRMdataAPI

Dokumentation · version 1.0.0

CRMdata API

Låt era egna system läsa och skriva det ni har i CRMdata: sparade företag, kontakter, anteckningar, händelser, uppgifter, affärer, ordrar, artiklar, taggar och ringlistor. Samma regler gäller som i appen. Med webhooks får ert system besked direkt när något händer.

Bas för alla anrop
/api/v1
Inloggning
API-nyckel i huvudet Authorization
Gräns
300 anrop per minut och nyckel

Prova direkt på sidan

Klistra in en API-nyckel här. Sedan kan du skicka riktiga anrop med knappen Prova vid varje slutpunkt och se svaret direkt.

Anropen görs på riktigt. Med en nyckel som får skriva ändrar anrop med POST, PATCH och DELETE riktig data i er organisation. Prova helst med en nyckel som bara får läsa.

Nyckeln finns bara i den här fliken så länge sidan är öppen. Den sparas inte i webbläsaren, hamnar inte i adressen och skickas bara till CRMdatas API. Ladda om sidan så är den borta.

Kom igång

  1. Skapa en nyckel

    Logga in i CRMdata som administratör och gå till Integrationer → API. Välj om nyckeln bara ska få läsa, eller både läsa och skriva. Nyckeln visas en enda gång, så spara den direkt på ett säkert ställe.

  2. Gör ett första anrop

    Lägg nyckeln i miljövariabeln CRMDATA_API_KEY och anropa GET /me. Anropet ändrar ingenting.

    curl "/api/v1/me" \
      -H "Authorization: Bearer $CRMDATA_API_KEY"

    Svaret

    {
      "organization": {
        "id": "7d2f9c4a1b8e4f06a3c5d9e2b1f04a77",
        "name": "Exempelbolaget AB",
        "slug": "exempelbolaget"
      },
      "key": {
        "id": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
        "name": "Webbformulär",
        "scope": "write",
        "prefix": "crmd_Ab12Cd34"
      },
      "limits": {
        "requestsPerMinute": 300,
        "maxBodyBytes": 1048576,
        "pageSizeDefault": 50,
        "pageSizeMax": 200
      }
    }
  3. Fortsätt med det ni behöver

    Varje resurs i innehållsförteckningen har sina slutpunkter med fält, exempel och knappen Prova, som skickar anropet direkt från sidan. Vill ni hellre läsa in API:t i ett verktyg som Postman finns OpenAPI-filen.

API:t ingår för organisationer med betalt abonnemang. Under provperioden går dokumentationen att läsa, men det går inte att skapa nycklar.

Inloggning

Varje anrop skickar nyckeln i huvudet Authorization. Det finns ingen annan inloggning.

Authorization: Bearer crmd_…
  • Nyckeln hör till organisationen, inte till en person. Det som skapas via API:t visas i appen som gjort av API och nyckelns namn, till exempel API (Webbformulär).
  • En nyckel får antingen bara läsa, eller läsa och skriva. Brickan vid varje slutpunkt visar vad som krävs: Nyckel: Läsa fungerar med alla nycklar, Nyckel: Läsa och skriva kräver en nyckel som får skriva.
  • Ha nyckeln på en server. Lägg den aldrig i en webbsida eller en app som andra kan öppna: den som har nyckeln kommer åt er data. Webbläsare släpper därför inte igenom anrop till API:t från andra webbplatser.
  • Har en nyckel kommit på avvägar? Dra in den under Integrationer → API. Den slutar gälla direkt, och ni skapar en ny. En organisation kan ha högst 10 nycklar samtidigt.

Svar och fel

Allt som skickas och tas emot är JSON.

  • Ett objekt svarar med objektet självt.
  • En lista svarar med { "data": [...], "nextCursor": "…" }. Se Listor och sidor.
  • När något skapas är svarskoden 201, och huvudet Location har adressen till det nya (utom för händelser och orderrader, som inte har någon egen adress).
  • När något tas bort är svarskoden 204, och svaret har inget innehåll.

Så ser ett fel ut

Alla fel har samma form. code är till för ert system, message är en text på svenska som går att visa för en människa, och details pekar ut fälten som inte stämmer.

{
  "error": {
    "code": "validation_failed",
    "message": "Innehållet stämmer inte. Se details för vad som behöver rättas.",
    "details": [
      {
        "field": "email",
        "message": "Ska vara en e-postadress."
      }
    ],
    "requestId": "req_8f3a1c2e9b7d4a6f"
  }
}
Fälten i ett fel
FältTypBeskrivning
codestringFelets kod, för ert system.
  • Värden:invalid_jsonvalidation_failedunknown_fieldmissing_keyinvalid_keyrevoked_keyread_only_keyplan_requiredforbiddennot_foundmethod_not_allowedconflictidempotency_key_reusedrequest_in_progresstoo_largeinvalidrate_limitedinternal_errorbusy
messagestringVad som gick fel, på svenska.
detailsobject[]Fälten som inte stämmer. Tom lista när felet inte gäller ett visst fält.
details: fieldstringFältet som inte stämmer, till exempel email eller rows[0].quantity.
details: messagestringVad som är fel med fältet.
requestIdstringAnropets id. Ange det om ni hör av er till oss.

Vissa fel har fler uppgifter bredvid de fyra, till exempel existingId när det ni försöker skapa redan finns. Hör ni av er till oss om ett fel: skicka med requestId, så hittar vi anropet.

Svarskoder och felkoder

Svarskoder och felkoder
SvarskodcodeNär
400invalid_jsonvalidation_failedunknown_fieldAnropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
401missing_keyinvalid_keyrevoked_keyIngen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
403read_only_keyplan_requiredforbiddenNyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
404not_foundFinns inte, eller hör till en annan organisation (samma svar).
405method_not_allowedMetoden finns inte för adressen. Huvudet Allow visar vilka metoder som finns.
409conflictidempotency_key_reusedrequest_in_progressKrockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
413too_largeInnehållet är större än 1 MB.
422invalidFormatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
429rate_limitedFör många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
500internal_errorEtt fel hos oss. Svaret har aldrig några detaljer, bara requestId.
503busyAPI:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Huvuden i svaren

Huvuden i svaren
HuvudBeskrivning
X-Request-IdAnropets id. Ange det om ni hör av er till oss.
Retry-AfterSekunder att vänta innan nästa försök.
X-RateLimit-LimitSå många anrop får nyckeln göra per minut.
X-RateLimit-RemainingSå många anrop återstår den här minuten.
X-RateLimit-ResetSekunder tills räkningen börjar om.
LocationAdressen till det som skapades.
Idempotent-Replayedtrue när svaret är en upprepning av ett tidigare anrop med samma Idempotency-Key.

Listor och sidor

Listor fungerar likadant i hela API:t. Svaret har raderna i data och en markör i nextCursor. Vilka parametrar en viss lista tar står vid slutpunkten.

  • limit: antal rader per sida, 1 till 200. Standard är 50.
  • cursor: värdet i nextCursor från förra svaret. Det ger nästa sida. När nextCursor är null finns det inga fler rader.
  • sort och order: sortera på createdAt (standard) eller updatedAt, med desc (nyast först, standard) eller asc (äldst först). Några listor har andra värden: Händelser (occurredAt), Uppgifter (dueAt). Vilka värden som gäller, och vilket som är standard, står vid slutpunkten.
  • updatedSince: bara det som ändrats efter en viss tidpunkt. Händelser ändras aldrig, så där gäller det som lagts till (createdAt).

En markör hör ihop med sorteringen. Använd samma sort och order på alla sidor i en hämtning, och skicka markören precis som ni fick den.

Stegvis synk

Så håller ni ett eget system uppdaterat utan att hämta allt varje gång:

  1. Första gången: hämta allt med sort=updatedAt&order=asc och följ nextCursor tills den är null.

  2. Spara det senaste updatedAt ni fick.

  3. Nästa gång: skicka det värdet som updatedSince, med samma sortering. Då kommer bara det som ändrats sedan dess.

# 1. Första gången: hämta allt, med den äldsta ändringen först
curl "/api/v1/companies?sort=updatedAt&order=asc&limit=200" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

# 2. Så länge nextCursor inte är null: hämta nästa sida
curl "/api/v1/companies?sort=updatedAt&order=asc&limit=200&cursor=<nextCursor>" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

# 3. Nästa gång: bara det som ändrats efter det senaste updatedAt ni sparade
curl "/api/v1/companies?sort=updatedAt&order=asc&limit=200&updatedSince=2026-10-05T12:00:00.000Z" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Exemplet är skrivet för curl. Hur samma anrop ser ut i JavaScript, Python och PowerShell visas vid varje slutpunkt.

Samma rad kan komma en gång till om den ändras medan ni hämtar. Spara därför med id som nyckel i ert system, så skrivs raden bara över. För händelser, som inte har updatedAt, används sort=createdAt&order=asc.

Vill ni hellre få besked direkt när något ändras, utan att fråga med jämna mellanrum? Se Webhooks.

Säkra omförsök

Om ett anrop som skapar något bryts av ett nätverksfel vet ni inte om det gick fram. Skicka därför huvudet Idempotency-Key med ett eget unikt värde, till exempel ett uuid, på anrop med POST. Då går anropet att skicka igen utan risk.

Idempotency-Key: 7c9e6679-7425-40de-944b-e07fc1f90ae7
  • Samma värde och samma innehåll inom 24 timmar ger samma svar igen, med huvudet Idempotent-Replayed: true. Inget skapas två gånger.
  • Samma värde med ett annat innehåll svarar 409 med koden idempotency_key_reused.
  • Pågår det första anropet fortfarande svarar API:t 409 med koden request_in_progress. Vänta en stund och försök igen.
  • Bara anrop som gick bra sparas. Efter ett fel går samma värde att använda igen.
  • Gäller inte POST /webhooks. Svaret har webhookens hemlighet och sparas därför aldrig. Läs där vad ni gör om svaret inte kom fram.

Värdet får vara högst 200 tecken.

Gränser

  • Anrop: högst 300 per minut och nyckel. Svaren visar läget i X-RateLimit-Limit, X-RateLimit-Remaining och X-RateLimit-Reset (sekunder tills räkningen börjar om). Över gränsen svarar API:t 429, och Retry-After säger hur många sekunder ni ska vänta.
  • Storlek: innehållet i ett anrop får vara högst 1 MB.
  • Listor: högst 200 rader per sida.
  • Nycklar: högst 10 per organisation.
  • Logg: under Integrationer → API ser ni de senaste anropen (adress, svarskod och tid) i 7 dagar. Innehållet i anropen sparas aldrig i loggen.

Fält och format

  • Namn: fältnamn är på engelska, till exempel visitCity och ownerUserId.
  • Id: uuid som text. Användare har ett kortare id som hämtas från listan över användare.
  • Tidpunkter: ISO 8601 i UTC, 2026-10-05T12:00:00.000Z. När ni skickar in en tidpunkt ska tidszonen stå med (Z eller +02:00). Datum utan klockslag skrivs 2026-10-05.
  • Pengar: kronor som tal med högst två decimaler, i fält som slutar på Sek. Nyckeltal från företagsdatan har enheten i namnet, till exempel Ksek för tusen kronor.
  • Tomma värden: svar har alltid alla fält. Ett fält utan värde är null.
  • Ändra med PATCH: fält som inte skickas lämnas orörda. null tömmer fältet, där det går.
  • Okända fält nekas med koden unknown_field, så att ett stavfel inte går obemärkt förbi.
  • Fält som bara går att läsa är märkta Bara läsa i tabellerna. Det gäller bland annat uppgifterna från företagsdatan: bransch och nyckeltal. Fält som anges när något skapas men inte går att ändra sedan, till exempel ett företags namn och organisationsnummer, är märkta Sätts när det skapas.
  • Personnummer sparas aldrig och lämnar aldrig API:t. Organisationsnummer för enskilda firmor visas maskerat (ÅÅMMDD-xxxx), och personnummer i text som skickas in maskeras på samma sätt.

Vad som inte ingår

  • Prospektera. Sökningen bland alla Sveriges företag finns bara i appen. API:t gäller era sparade företag, med deras uppgifter från företagsdatan. Skapar ni ett företag med organisationsnummer hämtas uppgifterna därifrån, precis som i appen.
  • Fakturor och Fortnox. Att göra om en order till faktura och skicka den till Fortnox görs i appen.
  • Mejl, kalender och filer. Mejl och möten från Outlook och uppladdade filer går inte att nå via API:t. En uppgift av typen möte bokas inte i Outlook.
  • Inställningar. Användare, roller, pipelines, import och kopplingar sköts i appen.

OpenAPI-filen

Hela API:t finns beskrivet i en OpenAPI-fil (version 3.1). Filen skapas ur samma kod som kör API:t, så den stämmer alltid. Den går att läsa utan nyckel.

/api/v1/openapi.json

Hämta OpenAPI-filen

  • Postman och Insomnia: välj Import och klistra in adressen. Då får ni alla anrop färdiga, med exempel.
  • Zapier, Make och liknande: använd deras modul för egna anrop (HTTP eller Webhooks) med adresserna härifrån, och lägg nyckeln i huvudet Authorization.
  • Egen kod: verktyg som OpenAPI Generator kan skapa en färdig klient ur filen.

Allmänt

Prova att nyckeln fungerar och hämta beskrivningen av API:t.

Prova nyckeln

Nyckel: Läsa

GET/api/v1/me

Visar vilken organisation nyckeln hör till, vad nyckeln får göra och vilka gränser som gäller. Ändrar ingenting: bra som första anrop för att se att nyckeln fungerar.

Exempel på anrop

curl "/api/v1/me" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

200OKDet gick bra.

Exempel på svar

{
  "organization": {
    "id": "7d2f9c4a1b8e4f06a3c5d9e2b1f04a77",
    "name": "Exempelbolaget AB",
    "slug": "exempelbolaget"
  },
  "key": {
    "id": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
    "name": "Webbformulär",
    "scope": "write",
    "prefix": "crmd_Ab12Cd34"
  },
  "limits": {
    "requestsPerMinute": 300,
    "maxBodyBytes": 1048576,
    "pageSizeDefault": 50,
    "pageSizeMax": 200
  }
}
Fälten i svaret (14): Me
Fält i svaret: Prova nyckeln
FältTypBeskrivning
organizationobjectOrganisationen som nyckeln hör till.
organization: idstringOrganisationens id.
organization: namestringOrganisationens namn.
organization: slugstringOrganisationens kortnamn.
keyobjectNyckeln som anropet gjordes med.
key: idstringNyckelns id (uuid).
key: namestringNamnet nyckeln fick när den skapades.
key: scopestringread = nyckeln får bara läsa. write = nyckeln får läsa och skriva.
  • Värden:readwrite
key: prefixstringNyckelns början, så som den visas i appen. Aldrig hela nyckeln.
limitsobjectGränserna som gäller för anropen.
limits: requestsPerMinuteintegerHögst så många anrop per minut med den här nyckeln.
limits: maxBodyBytesintegerStörsta innehåll i ett anrop, i byte.
limits: pageSizeDefaultintegerAntal rader per sida i listor när limit inte anges.
limits: pageSizeMaxintegerHögsta värdet för limit i listor.
Fel som kan komma400401403429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Hämta beskrivningen av API:t

Nyckel: Ingen nyckel

GET/api/v1/openapi.json

Hela API:t beskrivet som OpenAPI 3.1, för verktyg som läser sådana filer (till exempel för att skapa en klient eller prova anrop). Kräver ingen nyckel.

Exempel på anrop

curl "/api/v1/openapi.json"

Svar

200OKDet gick bra.

OpenAPI-dokumentet.

Fel som kan komma400500
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.

Alla fel har samma form. Se Svar och fel.

Företag

Era sparade företag, med uppgifterna från företagsdatan (bransch, nyckeltal, köpkraft) och era egna fält.

Lista företag

Nyckel: Läsa

GET/api/v1/companies

Era sparade företag, nyast först. Filtren går att kombinera: ett företag ska stämma med alla som anges. Arkiverade företag kommer bara med när archived=true. För att hämta det som ändrats sedan sist: sort=updatedAt&order=asc&updatedSince=<tidpunkt>.

Parametrar

Parametrar: Lista företag
NamnPlatsTypKrävsBeskrivning
limitFrågeparameterintegerNejAntal rader per sida, 1 till 200. Standard 50.
  • 1 till 200.
  • Standard:50
cursorFrågeparameterstringNejVärdet i nextCursor från förra svaret, för att hämta nästa sida. Utelämnas för första sidan.
  • 1 till 400 tecken.
sortFrågeparameterstringNejSortering: createdAt eller updatedAt. Standard createdAt.
  • Värden:createdAtupdatedAt
  • Standard:createdAt
orderFrågeparameterstringNejOrdning: desc (nyast först, standard) eller asc (äldst först).
  • Värden:ascdesc
  • Standard:desc
updatedSinceFrågeparameterstring (tidpunkt)NejBara det som ändrats efter den här tidpunkten: rader med updatedAt senare än den, räknat i millisekunder (raden med exakt samma updatedAt som ni skickar kommer inte med igen). För stegvis synk: sort=updatedAt&order=asc&updatedSince=<senaste updatedAt ni fått>.
qFrågeparameterstringNejSökord: träffar företag vars namn eller alias innehåller texten. Innehåller sökordet minst fyra siffror söks också organisationsnumret, utom för enskilda firmor (sök dem på namnet eller med orgNr). Ett personnummer i sökordet söks maskerat, ÅÅMMDD-xxxx, så som det visas.
  • Högst 200 tecken.
orgNrFrågeparameterstringNejOrganisationsnummer, i vilket vanligt skrivsätt som helst: 556123-4567, 5561234567 eller 165561234567. En enskild firma söks med det maskerade numret, ÅÅMMDD-xxxx; ett helt personnummer söks på samma sätt, som sitt maskerade nummer.
  • Högst 30 tecken.
tagFrågeparameterstringNejBara företag med den här taggen (taggens namn, utan hänsyn till stora och små bokstäver).
  • Högst 200 tecken.
ownerUserIdFrågeparameterstringNejBara företag där den här användaren är ansvarig.
  • 1 till 64 tecken.
countyCodeFrågeparameterstringNejBara företag i det här länet. SCB-kod med två siffror, till exempel 03 för Uppsala län.
  • Exakt 2 siffror.
municipalityCodeFrågeparameterstringNejBara företag i den här kommunen. SCB-kod med fyra siffror, till exempel 0380 för Uppsala.
  • Exakt 4 siffror.
archivedFrågeparameterstringNejtrue = bara arkiverade företag. Utelämnat eller false = bara företag som inte är arkiverade, som listan i appen.
  • Värden:truefalse

Exempel på anrop

curl "/api/v1/companies" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

200OKDet gick bra.

Exempel på svar

{
  "data": [
    {
      "id": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
      "customerNumber": 1042,
      "name": "Nordisk Fönsterteknik AB",
      "alias": "Fönsterteknik",
      "orgNr": "559900-1236",
      "isSoleProprietor": false,
      "legalFormCode": "AB",
      "legalForm": "Aktiebolag",
      "linkedToCompanyData": true,
      "companyDataDate": "2026-09-28",
      "sniCode": "43320",
      "sniLabel": "Byggnadssnickeriarbeten",
      "industryCode": "4120",
      "industryLabel": "Fönster och dörrar",
      "purchasingPower": "PP",
      "purchasingPowerLevel": 4,
      "keyFigures": {
        "fiscalYear": 2025,
        "revenueKsek": 48200,
        "netProfitKsek": 3100,
        "employees": 24,
        "previousRevenueKsek": 44750,
        "previousNetProfitKsek": 2650,
        "previousEmployees": 22
      },
      "status": "Offert",
      "ownerUserId": "pQ7mX2kV9sLwT4bN8cRd3fGh",
      "phone": "018-555 01 20",
      "email": "info@nordiskfonsterteknik.example",
      "website": "https://nordiskfonsterteknik.example",
      "visitStreet": "Verkstadsgatan 12",
      "visitPostalCode": "753 23",
      "visitCity": "Uppsala",
      "countyCode": "03",
      "countyName": "Uppsala län",
      "municipalityCode": "0380",
      "municipalityName": "Uppsala",
      "invoiceName": "Nordisk Fönsterteknik AB",
      "invoiceStreet": "Box 1234",
      "invoicePostalCode": "751 42",
      "invoiceCity": "Uppsala",
      "invoiceEmail": "faktura@nordiskfonsterteknik.example",
      "paymentTermsDays": 30,
      "description": "Tillverkar och monterar fönster åt bostadsrättsföreningar i Mälardalen.",
      "doNotContact": false,
      "doNotContactReason": null,
      "doNotContactAt": null,
      "tags": [
        "Mässa 2026",
        "VIP"
      ],
      "lastContactAt": "2026-10-02T08:15:00.000Z",
      "fortnoxCustomerNumber": "1042",
      "archivedAt": null,
      "createdBy": "pQ7mX2kV9sLwT4bN8cRd3fGh",
      "createdAt": "2026-03-14T09:30:00.000Z",
      "updatedAt": "2026-10-02T08:15:00.000Z"
    }
  ],
  "nextCursor": null
}
Fälten i svaret (55): Company
Fält i svaret: Lista företag
FältTypBeskrivning
dataCompany[]Raderna på den här sidan.
data: idBara läsastring (uuid)Företagets id i CRM:et (uuid).
data: customerNumberBara läsainteger eller nullKundnummer: ett löpnummer i organisationen som sätts när företaget sparas. Går bara att läsa.
data: nameSätts när det skapasstringFöretagets officiella namn. Kommer från företagsdatan när företaget är kopplat dit. Går bara att läsa; ert eget namn sätts i alias.
data: aliasstring eller nullErt eget namn på företaget. Visas under namnet i appen och går att söka på.
data: orgNrSätts när det skapasstring eller nullOrganisationsnummer, NNNNNN-NNNN. För en enskild firma är numret ägarens personnummer och visas därför bara maskerat, ÅÅMMDD-xxxx. Går bara att läsa.
data: isSoleProprietorBara läsabooleantrue om företaget är en enskild firma.
data: legalFormCodeBara läsastring eller nullBolagsform som kod, till exempel AB, HB, KB eller EF. Från företagsdatan: går bara att läsa.
data: legalFormBara läsastring eller nullBolagsform i klartext, till exempel Aktiebolag. Från företagsdatan: går bara att läsa.
data: linkedToCompanyDataBara läsabooleantrue när företaget är kopplat till företagsdatan (Sveriges företag). Då kommer namn, bolagsform, bransch, nyckeltal, köpkraft, län och kommun därifrån. false för ett företag som lagts till för hand.
data: companyDataDateBara läsastring (datum) eller nullDagen som uppgifterna från företagsdatan gäller för. null för företag utan koppling dit.
data: sniCodeBara läsastring eller nullBransch enligt SNI, koden. Från företagsdatan: går bara att läsa.
data: sniLabelBara läsastring eller nullBransch enligt SNI, i klartext. Från företagsdatan: går bara att läsa.
data: industryCodeBara läsastring eller nullCRMdatas egen bransch, koden. Från företagsdatan: går bara att läsa.
data: industryLabelBara läsastring eller nullCRMdatas egen bransch, i klartext. Från företagsdatan: går bara att läsa.
data: purchasingPowerBara läsastring eller nullKöpkraft: ett betyg i fem steg, P-, P, P+, PP eller PPP, där PPP är högst. Från företagsdatan: går bara att läsa.
data: purchasingPowerLevelBara läsainteger eller nullKöpkraften som tal, 1 (P-) till 5 (PPP), för den som vill sortera eller jämföra.
data: keyFiguresBara läsaobjectNyckeltal ur de två senaste boksluten. Alla värden är null för företag utan bokslut i företagsdatan. Från företagsdatan: går bara att läsa.
data.keyFigures: fiscalYearinteger eller nullÅret för det senaste bokslutet.
data.keyFigures: revenueKseknumber eller nullOmsättning i tusental kronor, senaste bokslutet.
data.keyFigures: netProfitKseknumber eller nullResultat i tusental kronor, senaste bokslutet.
data.keyFigures: employeesinteger eller nullAntal anställda, senaste bokslutet.
data.keyFigures: previousRevenueKseknumber eller nullOmsättning i tusental kronor, bokslutet före.
data.keyFigures: previousNetProfitKseknumber eller nullResultat i tusental kronor, bokslutet före.
data.keyFigures: previousEmployeesinteger eller nullAntal anställda, bokslutet före.
data: statusBara läsastringFöretagets status, räknad ur affärerna och ordrarna på samma sätt som i appen: Kund (minst en vunnen affär eller en order som inte är makulerad eller krediterad), annars namnet på steget för den senast ändrade öppna affären, annars Förlorad (bara förlorade affärer), annars Obearbetad. Går bara att läsa: ändra den genom att skapa eller flytta en affär.
data: ownerUserIdstring eller nullAnsvarig användare. null om ingen är ansvarig. Användarna hämtas med GET /users.
data: phonestring eller nullTelefonnummer (växel).
data: emailstring eller nullE-postadress till företaget.
data: websitestring eller nullWebbplats.
data: visitStreetstring eller nullBesöksadress: gata.
data: visitPostalCodestring eller nullBesöksadress: postnummer.
data: visitCitystring eller nullBesöksadress: ort.
data: countyCodestring eller nullLän som SCB-kod, två siffror (03 = Uppsala län). På kopplade företag från företagsdatan.
data: countyNameBara läsastring eller nullLänets namn.
data: municipalityCodestring eller nullKommun som SCB-kod, fyra siffror (0380 = Uppsala). På kopplade företag från företagsdatan.
data: municipalityNameBara läsastring eller nullKommunens namn.
data: invoiceNamestring eller nullFakturauppgifter: mottagarens namn.
data: invoiceStreetstring eller nullFakturauppgifter: gata eller box.
data: invoicePostalCodestring eller nullFakturauppgifter: postnummer.
data: invoiceCitystring eller nullFakturauppgifter: ort.
data: invoiceEmailstring eller nullFakturauppgifter: e-postadress som fakturor skickas till.
data: paymentTermsDaysinteger eller nullBetalningsvillkor i dagar.
data: descriptionstring eller nullBeskrivning av företaget.
data: doNotContactbooleantrue om företaget är spärrat för kontakt. Ett spärrat företag kommer inte med i ringlistor och utskick.
data: doNotContactReasonstring eller nullSkälet till spärren. null om företaget inte är spärrat eller inget skäl angavs.
data: doNotContactAtBara läsastring (tidpunkt) eller nullNär spärren sattes. null om företaget inte är spärrat.
data: tagsstring[]Företagets taggar, som namn i bokstavsordning.
data: lastContactAtBara läsastring (tidpunkt) eller nullSenaste kontakt: det senaste samtalet, mejlet eller mötet som loggats på företaget. Anteckningar räknas inte. Går bara att läsa.
data: fortnoxCustomerNumberBara läsastring eller nullKundnumret i ert Fortnox, när företaget har förts över dit. Går bara att läsa.
data: archivedAtBara läsastring (tidpunkt) eller nullNär företaget arkiverades. null för ett företag som inte är arkiverat. Går bara att läsa.
data: createdByBara läsastring eller nullAnvändaren som sparade företaget. null när det skapades via API:t eller en import.
data: createdAtBara läsastring (tidpunkt)När företaget sparades.
data: updatedAtBara läsastring (tidpunkt)När företaget senast ändrades.
nextCursorstring eller nullSkicka som cursor för att hämta nästa sida. null när det inte finns fler rader.

Bara läsa: fältet finns i svaren men går inte att skicka in.

Sätts när det skapas: fältet anges när objektet skapas (POST) och går sedan inte att ändra.

Fel som kan komma400401403429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Lägg till ett företag

Nyckel: Läsa och skriva

POST/api/v1/companies

Sparar ett nytt företag, på samma sätt som Nytt företag i appen. Med organisationsnummer letas företaget upp i företagsdatan: finns det där sparas det därifrån, med officiellt namn, bolagsform, bransch, nyckeltal och köpkraft, och det ni skickade fyller i det som saknas (telefon, e-post, webbplats och besöksadress). Finns det inte där, eller skickas inget organisationsnummer, sparas företaget med det ni skickade. Har ni redan ett sparat företag med samma organisationsnummer skapas inget nytt: svaret är 409 med det befintliga företagets id i existingId. Företaget får ett kundnummer och händelsen syns i tidslinjen. Ansvarig, alias och taggar sätts efteråt med PATCH. Högst 500 nya företag per nyckel och dag (svensk tid): över det svarar API:t 429 rate_limited med Retry-After, sekunderna till midnatt. Ett anrop som inte skapar något företag (till exempel 409) räknas inte.

Parametrar

Parametrar: Lägg till ett företag
NamnPlatsTypKrävsBeskrivning
Idempotency-KeyHuvudstringNejGör anropet säkert att skicka igen: samma nyckel och samma innehåll inom 24 timmar ger samma svar utan att något skapas två gånger. Till exempel ett uuid.
  • 1 till 200 tecken.

Innehåll

Skickas som JSON i anropet. Okända fält nekas.

Fält att skicka: Lägg till ett företag
FältTypKrävsBeskrivning
namestringJaKrävsFöretagets namn. Finns organisationsnumret i företagsdatan används det officiella namnet därifrån i stället.
  • 1 till 200 tecken.
orgNrstring eller nullNejOrganisationsnummer med 10 siffror, med eller utan bindestreck (556123-4567). Valfritt. För en enskild firma är numret ägarens personnummer: det används bara för att känna igen firman och sparas maskerat (ÅÅMMDD-xxxx).
  • Högst 30 tecken.
visitStreetstring eller nullNejBesöksadress: gata.
  • Högst 200 tecken.
visitPostalCodestring eller nullNejBesöksadress: postnummer.
  • Högst 20 tecken.
visitCitystring eller nullNejBesöksadress: ort. Heter orten som en kommun sätts län och kommun efter den.
  • Högst 100 tecken.
phonestring eller nullNejTelefonnummer (växel). Ett personnummer godtas inte.
  • Högst 50 tecken.
emailstring eller nullNejE-postadress till företaget.
  • Högst 200 tecken.
websitestring eller nullNejWebbplats.
  • Högst 300 tecken.

Exempel på anrop

curl -X POST "/api/v1/companies" \
  -H "Authorization: Bearer $CRMDATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Nordisk Fönsterteknik AB",
  "orgNr": "559900-1236",
  "phone": "018-555 01 20",
  "email": "info@nordiskfonsterteknik.example",
  "visitCity": "Uppsala"
}'

Svar

201SkapatSkapat. Location har adressen till det som skapades.

Exempel på svar

{
  "id": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
  "customerNumber": 1042,
  "name": "Nordisk Fönsterteknik AB",
  "alias": null,
  "orgNr": "559900-1236",
  "isSoleProprietor": false,
  "legalFormCode": "AB",
  "legalForm": "Aktiebolag",
  "linkedToCompanyData": true,
  "companyDataDate": "2026-09-28",
  "sniCode": "43320",
  "sniLabel": "Byggnadssnickeriarbeten",
  "industryCode": "4120",
  "industryLabel": "Fönster och dörrar",
  "purchasingPower": "PP",
  "purchasingPowerLevel": 4,
  "keyFigures": {
    "fiscalYear": 2025,
    "revenueKsek": 48200,
    "netProfitKsek": 3100,
    "employees": 24,
    "previousRevenueKsek": 44750,
    "previousNetProfitKsek": 2650,
    "previousEmployees": 22
  },
  "status": "Obearbetad",
  "ownerUserId": null,
  "phone": "018-555 01 20",
  "email": "info@nordiskfonsterteknik.example",
  "website": "https://nordiskfonsterteknik.example",
  "visitStreet": "Verkstadsgatan 12",
  "visitPostalCode": "753 23",
  "visitCity": "Uppsala",
  "countyCode": "03",
  "countyName": "Uppsala län",
  "municipalityCode": "0380",
  "municipalityName": "Uppsala",
  "invoiceName": "Nordisk Fönsterteknik AB",
  "invoiceStreet": "Box 1234",
  "invoicePostalCode": "751 42",
  "invoiceCity": "Uppsala",
  "invoiceEmail": "faktura@nordiskfonsterteknik.example",
  "paymentTermsDays": 30,
  "description": "Tillverkar och monterar fönster åt bostadsrättsföreningar i Mälardalen.",
  "doNotContact": false,
  "doNotContactReason": null,
  "doNotContactAt": null,
  "tags": [],
  "lastContactAt": null,
  "fortnoxCustomerNumber": null,
  "archivedAt": null,
  "createdBy": null,
  "createdAt": "2026-10-05T12:00:00.000Z",
  "updatedAt": "2026-10-05T12:00:00.000Z"
}

Fälten i svaret (Company) är samma som i Lista företag.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Hämta ett företag

Nyckel: Läsa

GET/api/v1/companies/{id}

Ett sparat företag med uppgifterna från företagsdatan, era egna fält, status och taggar.

Parametrar

Parametrar: Hämta ett företag
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsId (uuid).

Exempel på anrop

curl "/api/v1/companies/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

200OKDet gick bra.

Exempel på svar

{
  "id": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
  "customerNumber": 1042,
  "name": "Nordisk Fönsterteknik AB",
  "alias": "Fönsterteknik",
  "orgNr": "559900-1236",
  "isSoleProprietor": false,
  "legalFormCode": "AB",
  "legalForm": "Aktiebolag",
  "linkedToCompanyData": true,
  "companyDataDate": "2026-09-28",
  "sniCode": "43320",
  "sniLabel": "Byggnadssnickeriarbeten",
  "industryCode": "4120",
  "industryLabel": "Fönster och dörrar",
  "purchasingPower": "PP",
  "purchasingPowerLevel": 4,
  "keyFigures": {
    "fiscalYear": 2025,
    "revenueKsek": 48200,
    "netProfitKsek": 3100,
    "employees": 24,
    "previousRevenueKsek": 44750,
    "previousNetProfitKsek": 2650,
    "previousEmployees": 22
  },
  "status": "Offert",
  "ownerUserId": "pQ7mX2kV9sLwT4bN8cRd3fGh",
  "phone": "018-555 01 20",
  "email": "info@nordiskfonsterteknik.example",
  "website": "https://nordiskfonsterteknik.example",
  "visitStreet": "Verkstadsgatan 12",
  "visitPostalCode": "753 23",
  "visitCity": "Uppsala",
  "countyCode": "03",
  "countyName": "Uppsala län",
  "municipalityCode": "0380",
  "municipalityName": "Uppsala",
  "invoiceName": "Nordisk Fönsterteknik AB",
  "invoiceStreet": "Box 1234",
  "invoicePostalCode": "751 42",
  "invoiceCity": "Uppsala",
  "invoiceEmail": "faktura@nordiskfonsterteknik.example",
  "paymentTermsDays": 30,
  "description": "Tillverkar och monterar fönster åt bostadsrättsföreningar i Mälardalen.",
  "doNotContact": false,
  "doNotContactReason": null,
  "doNotContactAt": null,
  "tags": [
    "Mässa 2026",
    "VIP"
  ],
  "lastContactAt": "2026-10-02T08:15:00.000Z",
  "fortnoxCustomerNumber": "1042",
  "archivedAt": null,
  "createdBy": "pQ7mX2kV9sLwT4bN8cRd3fGh",
  "createdAt": "2026-03-14T09:30:00.000Z",
  "updatedAt": "2026-10-02T08:15:00.000Z"
}

Fälten i svaret (Company) är samma som i Lista företag.

Fel som kan komma400401403404429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Ändra ett företag

Nyckel: Läsa och skriva

PATCH/api/v1/companies/{id}

Ändrar era egna uppgifter på företaget: alias, ansvarig, telefon, e-post, webbplats, adresser, fakturauppgifter, betalningsvillkor, beskrivning, spärren för kontakt och taggarna. Fält som inte skickas lämnas orörda, och null tömmer fältet. Uppgifterna från företagsdatan (namn, organisationsnummer, bolagsform, bransch, nyckeltal och köpkraft) går inte att ändra, och inte heller län och kommun på ett företag som är kopplat dit. Ett företag går inte att arkivera eller ta bort via API:t. Allt kontrolleras innan något sparas.

Parametrar

Parametrar: Ändra ett företag
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsId (uuid).

Innehåll

Skickas som JSON i anropet. Okända fält nekas.

Fält att skicka: Ändra ett företag
FältTypKrävsBeskrivning
aliasstring eller nullNejErt eget namn på företaget. null tar bort aliaset.
  • Högst 120 tecken.
ownerUserIdstring eller nullNejAnsvarig användare. Måste vara en användare i organisationen (GET /users). null = ingen ansvarig.
  • 1 till 64 tecken.
phonestring eller nullNejTelefonnummer (växel). Ett personnummer godtas inte.
  • Högst 50 tecken.
emailstring eller nullNejE-postadress till företaget.
  • Högst 200 tecken.
websitestring eller nullNejWebbplats.
  • Högst 300 tecken.
visitStreetstring eller nullNejBesöksadress: gata.
  • Högst 200 tecken.
visitPostalCodestring eller nullNejBesöksadress: postnummer.
  • Högst 20 tecken.
visitCitystring eller nullNejBesöksadress: ort.
  • Högst 100 tecken.
countyCodestring eller nullNejLän som SCB-kod, två siffror. Går bara att ändra på företag som inte är kopplade till företagsdatan. Ett annat län tar bort en kommun som inte ligger där; null tar bort både län och kommun.
  • Exakt 2 siffror.
municipalityCodestring eller nullNejKommun som SCB-kod, fyra siffror. Går bara att ändra på företag som inte är kopplade till företagsdatan. Kommunen bestämmer länet. null tar bort kommunen.
  • Exakt 4 siffror.
invoiceNamestring eller nullNejFakturauppgifter: mottagarens namn.
  • Högst 200 tecken.
invoiceStreetstring eller nullNejFakturauppgifter: gata eller box.
  • Högst 200 tecken.
invoicePostalCodestring eller nullNejFakturauppgifter: postnummer.
  • Högst 20 tecken.
invoiceCitystring eller nullNejFakturauppgifter: ort.
  • Högst 100 tecken.
invoiceEmailstring eller nullNejFakturauppgifter: e-postadress som fakturor skickas till.
  • Högst 200 tecken.
paymentTermsDaysintegerNejBetalningsvillkor i dagar, 0 till 120. Går inte att tömma.
  • 0 till 120.
descriptionstring eller nullNejBeskrivning av företaget.
  • Högst 5 000 tecken.
doNotContactbooleanNejtrue spärrar företaget för kontakt (det kommer inte med i ringlistor och utskick). false tar bort spärren.
doNotContactReasonstring eller nullNejSkälet till spärren, till exempel Begärt av företaget. Kan bara anges tillsammans med doNotContact: true.
  • Högst 200 tecken.
tagsstring[]NejHela listan med företagets taggar, som namn. Taggar som inte står med tas bort från företaget, och de som saknas läggs till. En tagg som inte finns i organisationen skapas (högst 40 tecken). En tom lista tar bort alla taggar.
  • Högst 100 värden. Varje värde: 1 till 200 tecken.

Exempel på anrop

curl -X PATCH "/api/v1/companies/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a" \
  -H "Authorization: Bearer $CRMDATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "alias": "Fönsterteknik",
  "ownerUserId": "pQ7mX2kV9sLwT4bN8cRd3fGh",
  "invoiceEmail": "faktura@nordiskfonsterteknik.example",
  "paymentTermsDays": 30,
  "tags": [
    "VIP",
    "Mässa 2026"
  ]
}'

Svar

200OKDet gick bra.

Exempel på svar

{
  "id": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
  "customerNumber": 1042,
  "name": "Nordisk Fönsterteknik AB",
  "alias": "Fönsterteknik",
  "orgNr": "559900-1236",
  "isSoleProprietor": false,
  "legalFormCode": "AB",
  "legalForm": "Aktiebolag",
  "linkedToCompanyData": true,
  "companyDataDate": "2026-09-28",
  "sniCode": "43320",
  "sniLabel": "Byggnadssnickeriarbeten",
  "industryCode": "4120",
  "industryLabel": "Fönster och dörrar",
  "purchasingPower": "PP",
  "purchasingPowerLevel": 4,
  "keyFigures": {
    "fiscalYear": 2025,
    "revenueKsek": 48200,
    "netProfitKsek": 3100,
    "employees": 24,
    "previousRevenueKsek": 44750,
    "previousNetProfitKsek": 2650,
    "previousEmployees": 22
  },
  "status": "Offert",
  "ownerUserId": "pQ7mX2kV9sLwT4bN8cRd3fGh",
  "phone": "018-555 01 20",
  "email": "info@nordiskfonsterteknik.example",
  "website": "https://nordiskfonsterteknik.example",
  "visitStreet": "Verkstadsgatan 12",
  "visitPostalCode": "753 23",
  "visitCity": "Uppsala",
  "countyCode": "03",
  "countyName": "Uppsala län",
  "municipalityCode": "0380",
  "municipalityName": "Uppsala",
  "invoiceName": "Nordisk Fönsterteknik AB",
  "invoiceStreet": "Box 1234",
  "invoicePostalCode": "751 42",
  "invoiceCity": "Uppsala",
  "invoiceEmail": "faktura@nordiskfonsterteknik.example",
  "paymentTermsDays": 30,
  "description": "Tillverkar och monterar fönster åt bostadsrättsföreningar i Mälardalen.",
  "doNotContact": false,
  "doNotContactReason": null,
  "doNotContactAt": null,
  "tags": [
    "Mässa 2026",
    "VIP"
  ],
  "lastContactAt": "2026-10-02T08:15:00.000Z",
  "fortnoxCustomerNumber": "1042",
  "archivedAt": null,
  "createdBy": "pQ7mX2kV9sLwT4bN8cRd3fGh",
  "createdAt": "2026-03-14T09:30:00.000Z",
  "updatedAt": "2026-10-02T08:15:00.000Z"
}

Fälten i svaret (Company) är samma som i Lista företag.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Kontakter

Kontaktpersoner på era sparade företag.

Lista kontakter

Nyckel: Läsa

GET/api/v1/contacts

Kontakterna på organisationens sparade företag, nyast först. Med companyId: bara kontakterna på det företaget. Med email går det att slå upp vem en e-postadress hör till, och q söker i namn och e-postadress.

Parametrar

Parametrar: Lista kontakter
NamnPlatsTypKrävsBeskrivning
limitFrågeparameterintegerNejAntal rader per sida, 1 till 200. Standard 50.
  • 1 till 200.
  • Standard:50
cursorFrågeparameterstringNejVärdet i nextCursor från förra svaret, för att hämta nästa sida. Utelämnas för första sidan.
  • 1 till 400 tecken.
sortFrågeparameterstringNejSortering: createdAt eller updatedAt. Standard createdAt.
  • Värden:createdAtupdatedAt
  • Standard:createdAt
orderFrågeparameterstringNejOrdning: desc (nyast först, standard) eller asc (äldst först).
  • Värden:ascdesc
  • Standard:desc
updatedSinceFrågeparameterstring (tidpunkt)NejBara det som ändrats efter den här tidpunkten: rader med updatedAt senare än den, räknat i millisekunder (raden med exakt samma updatedAt som ni skickar kommer inte med igen). För stegvis synk: sort=updatedAt&order=asc&updatedSince=<senaste updatedAt ni fått>.
companyIdFrågeparameterstring (uuid)NejBara kontakter på det här företaget.
emailFrågeparameterstringNejBara kontakter med exakt den här e-postadressen. Stora och små bokstäver spelar ingen roll.
  • 1 till 200 tecken.
qFrågeparameterstringNejSök i namn och e-postadress. En del av texten räcker. Ett personnummer söks maskerat, ÅÅMMDD-xxxx, så som det visas.
  • 1 till 100 tecken.

Exempel på anrop

curl "/api/v1/contacts" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

200OKDet gick bra.

Exempel på svar

{
  "data": [
    {
      "id": "7c1d2e3f-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
      "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
      "name": "Anna Lindqvist",
      "firstName": "Anna",
      "lastName": "Lindqvist",
      "title": "Inköpschef",
      "email": "anna.lindqvist@exempelbolaget.se",
      "phone": "08-465 004 12",
      "mobile": "070-174 06 12",
      "linkedinUrl": "https://www.linkedin.com/in/anna-lindqvist-exempel",
      "notes": "Nås bäst på förmiddagar.",
      "isPrimary": true,
      "source": "manual",
      "createdBy": null,
      "createdAt": "2026-10-05T12:00:00.000Z",
      "updatedAt": "2026-10-05T12:00:00.000Z"
    }
  ],
  "nextCursor": null
}
Fälten i svaret (18): Contact
Fält i svaret: Lista kontakter
FältTypBeskrivning
dataContact[]Raderna på den här sidan.
data: idBara läsastring (uuid)Id (uuid).
data: companyIdSätts när det skapasstring (uuid)Företaget som kontakten hör till.
data: namestringFullständigt namn. Alltid ifyllt. På en styrelsekontakt (source board) kommer namnet från företagsdatan och går bara att läsa.
data: firstNamestring eller nullFörnamn, för den som vill ha namnet uppdelat. null om det inte är ifyllt.
data: lastNamestring eller nullEfternamn, för den som vill ha namnet uppdelat. null om det inte är ifyllt.
data: titlestring eller nullTitel eller roll, till exempel Inköpschef. På en styrelsekontakt (source board) är det rollen i bolaget, till exempel Verkställande direktör: den kommer från företagsdatan och går bara att läsa.
data: emailstring eller nullE-postadress.
data: phonestring eller nullTelefonnummer, så som det är skrivet.
data: mobilestring eller nullMobilnummer, så som det är skrivet.
data: linkedinUrlstring eller nullLänk till kontaktens sida på LinkedIn.
data: notesstring eller nullEgen notering om kontakten.
data: isPrimarybooleantrue för företagets huvudkontakt. Ett företag har högst en.
data: sourceBara läsastringVarifrån kontakten kommer. manual = tillagd för hand eller via API:t. board = företagets ansvariga person, hämtad från företagsdatan när företaget sparades (namn och roll är låsta). import = från en importerad fil. email = skapad utifrån ett mejl.
  • Värden:manualboardimportemail
data: createdByBara läsastring eller nullAnvändaren som lade till kontakten. null när den lades till via API:t.
data: createdAtBara läsastring (tidpunkt)När kontakten lades till.
data: updatedAtBara läsastring (tidpunkt)När kontakten senast ändrades.
nextCursorstring eller nullSkicka som cursor för att hämta nästa sida. null när det inte finns fler rader.

Bara läsa: fältet finns i svaren men går inte att skicka in.

Sätts när det skapas: fältet anges när objektet skapas (POST) och går sedan inte att ändra.

Fel som kan komma400401403429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Lägg till en kontakt

Nyckel: Läsa och skriva

POST/api/v1/contacts

Lägger till en kontakt på ett sparat företag, precis som + Ny kontakt i appen. Namnet måste finnas: antingen name, eller firstName och lastName som då sätts ihop. Företagets första kontakt blir huvudkontakt. Kontakten syns i företagets tidslinje. Har någon i organisationen kopplat sin Outlook hämtas äldre mejl till och från e-postadressen i bakgrunden. Samma person kan läggas till flera gånger: slå upp e-postadressen med GET /contacts?email=… först om ni vill undvika dubbletter.

Parametrar

Parametrar: Lägg till en kontakt
NamnPlatsTypKrävsBeskrivning
Idempotency-KeyHuvudstringNejGör anropet säkert att skicka igen: samma nyckel och samma innehåll inom 24 timmar ger samma svar utan att något skapas två gånger. Till exempel ett uuid.
  • 1 till 200 tecken.

Innehåll

Skickas som JSON i anropet. Okända fält nekas.

Fält att skicka: Lägg till en kontakt
FältTypKrävsBeskrivning
companyIdstring (uuid)JaKrävsFöretaget som kontakten ska läggas på.
namestring eller nullNejFullständigt namn. Utelämnas det sätts namnet ihop av firstName och lastName. Namnet eller minst en av delarna måste finnas.
  • Högst 200 tecken.
firstNamestring eller nullNejFörnamn.
  • Högst 100 tecken.
lastNamestring eller nullNejEfternamn.
  • Högst 100 tecken.
titlestring eller nullNejTitel eller roll, till exempel Inköpschef.
  • Högst 200 tecken.
emailstring eller nullNejE-postadress.
  • Högst 200 tecken.
phonestring eller nullNejTelefonnummer. Ett personnummer godtas inte.
  • Högst 50 tecken.
mobilestring eller nullNejMobilnummer. Ett personnummer godtas inte.
  • Högst 50 tecken.
linkedinUrlstring eller nullNejLänk till kontaktens sida på LinkedIn. Bara adresser på linkedin.com godtas (annars 422 med fältet linkedinUrl); länken sparas med https://.
  • Högst 300 tecken.
notesstring eller nullNejEgen notering om kontakten. Personnummer i texten maskeras.
  • Högst 2 000 tecken.

Exempel på anrop

curl -X POST "/api/v1/contacts" \
  -H "Authorization: Bearer $CRMDATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
  "firstName": "Anna",
  "lastName": "Lindqvist",
  "title": "Inköpschef",
  "email": "anna.lindqvist@exempelbolaget.se",
  "mobile": "070-174 06 12"
}'

Svar

201SkapatSkapat. Location har adressen till det som skapades.

Exempel på svar

{
  "id": "7c1d2e3f-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
  "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
  "name": "Anna Lindqvist",
  "firstName": "Anna",
  "lastName": "Lindqvist",
  "title": "Inköpschef",
  "email": "anna.lindqvist@exempelbolaget.se",
  "phone": null,
  "mobile": "070-174 06 12",
  "linkedinUrl": null,
  "notes": null,
  "isPrimary": true,
  "source": "manual",
  "createdBy": null,
  "createdAt": "2026-10-05T12:00:00.000Z",
  "updatedAt": "2026-10-05T12:00:00.000Z"
}

Fälten i svaret (Contact) är samma som i Lista kontakter.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Hämta en kontakt

Nyckel: Läsa

GET/api/v1/contacts/{id}

En kontakt med alla sina uppgifter.

Parametrar

Parametrar: Hämta en kontakt
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsId (uuid).

Exempel på anrop

curl "/api/v1/contacts/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

200OKDet gick bra.

Exempel på svar

{
  "id": "7c1d2e3f-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
  "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
  "name": "Anna Lindqvist",
  "firstName": "Anna",
  "lastName": "Lindqvist",
  "title": "Inköpschef",
  "email": "anna.lindqvist@exempelbolaget.se",
  "phone": "08-465 004 12",
  "mobile": "070-174 06 12",
  "linkedinUrl": "https://www.linkedin.com/in/anna-lindqvist-exempel",
  "notes": "Nås bäst på förmiddagar.",
  "isPrimary": true,
  "source": "manual",
  "createdBy": null,
  "createdAt": "2026-10-05T12:00:00.000Z",
  "updatedAt": "2026-10-05T12:00:00.000Z"
}

Fälten i svaret (Contact) är samma som i Lista kontakter.

Fel som kan komma400401403404429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Ändra en kontakt

Nyckel: Läsa och skriva

PATCH/api/v1/contacts/{id}

Ändrar en kontakts uppgifter. Fält som inte skickas lämnas orörda, och null tömmer fältet. Namnet går inte att ta bort: med name null sätts det ihop av firstName och lastName. name ändras inte av att bara firstName eller lastName ändras. isPrimary true gör kontakten till företagets huvudkontakt. På en styrelsekontakt (source board) kommer namn och roll från företagsdatan: name och title går inte att ändra där, övriga fält går bra. En ny e-postadress gör att äldre mejl till och från den hämtas i bakgrunden, om någon har kopplat sin Outlook.

Parametrar

Parametrar: Ändra en kontakt
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsId (uuid).

Innehåll

Skickas som JSON i anropet. Okända fält nekas.

Fält att skicka: Ändra en kontakt
FältTypKrävsBeskrivning
namestring eller nullNejFullständigt namn. null: namnet sätts ihop av firstName och lastName. Går inte att ändra på en styrelsekontakt (source board).
  • Högst 200 tecken.
firstNamestring eller nullNejFörnamn.
  • Högst 100 tecken.
lastNamestring eller nullNejEfternamn.
  • Högst 100 tecken.
titlestring eller nullNejTitel eller roll. Går inte att ändra på en styrelsekontakt (source board).
  • Högst 200 tecken.
emailstring eller nullNejE-postadress.
  • Högst 200 tecken.
phonestring eller nullNejTelefonnummer. Ett personnummer godtas inte.
  • Högst 50 tecken.
mobilestring eller nullNejMobilnummer. Ett personnummer godtas inte.
  • Högst 50 tecken.
linkedinUrlstring eller nullNejLänk till kontaktens sida på LinkedIn. Bara adresser på linkedin.com godtas (annars 422 med fältet linkedinUrl); länken sparas med https://.
  • Högst 300 tecken.
notesstring eller nullNejEgen notering om kontakten. Personnummer i texten maskeras.
  • Högst 2 000 tecken.
isPrimarybooleanNejtrue gör kontakten till företagets huvudkontakt; den som var det förut slutar vara det. En huvudkontakt tas inte bort med false: gör en annan kontakt till huvudkontakt i stället.

Exempel på anrop

curl -X PATCH "/api/v1/contacts/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a" \
  -H "Authorization: Bearer $CRMDATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "title": "Inköpsdirektör",
  "mobile": "070-174 06 12",
  "isPrimary": true
}'

Svar

200OKDet gick bra.

Exempel på svar

{
  "id": "7c1d2e3f-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
  "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
  "name": "Anna Lindqvist",
  "firstName": "Anna",
  "lastName": "Lindqvist",
  "title": "Inköpsdirektör",
  "email": "anna.lindqvist@exempelbolaget.se",
  "phone": "08-465 004 12",
  "mobile": "070-174 06 12",
  "linkedinUrl": "https://www.linkedin.com/in/anna-lindqvist-exempel",
  "notes": "Nås bäst på förmiddagar.",
  "isPrimary": true,
  "source": "manual",
  "createdBy": null,
  "createdAt": "2026-10-05T12:00:00.000Z",
  "updatedAt": "2026-10-06T08:30:00.000Z"
}

Fälten i svaret (Contact) är samma som i Lista kontakter.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Radera en kontakt

Nyckel: Läsa och skriva

DELETE/api/v1/contacts/{id}

Raderar kontakten för gott. Det går inte att ångra. Anteckningar, uppgifter och händelser som pekade på kontakten finns kvar, utan kontakt. Raderas huvudkontakten står företaget utan huvudkontakt tills en annan kontakt görs till det.

Parametrar

Parametrar: Radera en kontakt
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsId (uuid).

Exempel på anrop

curl -X DELETE "/api/v1/contacts/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

204Inget innehållDet gick bra. Svaret har inget innehåll.

Svaret har inget innehåll.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Anteckningar

Anteckningar på företag.

Lista anteckningar

Nyckel: Läsa

GET/api/v1/notes

Anteckningarna i organisationen, nyast först. Med companyId: bara anteckningarna på det företaget.

Parametrar

Parametrar: Lista anteckningar
NamnPlatsTypKrävsBeskrivning
limitFrågeparameterintegerNejAntal rader per sida, 1 till 200. Standard 50.
  • 1 till 200.
  • Standard:50
cursorFrågeparameterstringNejVärdet i nextCursor från förra svaret, för att hämta nästa sida. Utelämnas för första sidan.
  • 1 till 400 tecken.
sortFrågeparameterstringNejSortering: createdAt eller updatedAt. Standard createdAt.
  • Värden:createdAtupdatedAt
  • Standard:createdAt
orderFrågeparameterstringNejOrdning: desc (nyast först, standard) eller asc (äldst först).
  • Värden:ascdesc
  • Standard:desc
updatedSinceFrågeparameterstring (tidpunkt)NejBara det som ändrats efter den här tidpunkten: rader med updatedAt senare än den, räknat i millisekunder (raden med exakt samma updatedAt som ni skickar kommer inte med igen). För stegvis synk: sort=updatedAt&order=asc&updatedSince=<senaste updatedAt ni fått>.
companyIdFrågeparameterstring (uuid)NejBara anteckningar på det här företaget.

Exempel på anrop

curl "/api/v1/notes" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

200OKDet gick bra.

Exempel på svar

{
  "data": [
    {
      "id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
      "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
      "contactId": "7c1d2e3f-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
      "title": "Möte online",
      "body": "Gick igenom offerten med Anna. De vill ha ett pris på tre år i stället för två och återkommer efter styrelsemötet i november.",
      "createdBy": null,
      "createdAt": "2026-10-05T12:00:00.000Z",
      "updatedAt": "2026-10-05T12:00:00.000Z"
    }
  ],
  "nextCursor": null
}
Fälten i svaret (10): Note
Fält i svaret: Lista anteckningar
FältTypBeskrivning
dataNote[]Raderna på den här sidan.
data: idBara läsastring (uuid)Id (uuid).
data: companyIdstring (uuid)Företaget som anteckningen hör till.
data: contactIdstring (uuid) eller nullKontakten på företaget som anteckningen gäller. null om ingen är vald.
data: titlestring eller nullRubrik, till exempel Möte online. null om anteckningen saknar rubrik.
data: bodystringAnteckningens text.
data: createdByBara läsastring eller nullAnvändaren som skrev anteckningen. null när den skapades via API:t.
data: createdAtBara läsastring (tidpunkt)När anteckningen skrevs.
data: updatedAtBara läsastring (tidpunkt)När anteckningen senast ändrades. Anteckningar går inte att ändra, så det är i regel samma tid som createdAt.
nextCursorstring eller nullSkicka som cursor för att hämta nästa sida. null när det inte finns fler rader.

Bara läsa: fältet finns i svaren men går inte att skicka in.

Fel som kan komma400401403429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Skriv en anteckning

Nyckel: Läsa och skriva

POST/api/v1/notes

Skriver en anteckning på ett sparat företag. Den syns under Anteckningar och i företagets tidslinje, precis som en anteckning skriven i appen. En anteckning räknas inte som kontakt: ska ett samtal, möte eller mejl loggas, använd POST /activities.

Parametrar

Parametrar: Skriv en anteckning
NamnPlatsTypKrävsBeskrivning
Idempotency-KeyHuvudstringNejGör anropet säkert att skicka igen: samma nyckel och samma innehåll inom 24 timmar ger samma svar utan att något skapas två gånger. Till exempel ett uuid.
  • 1 till 200 tecken.

Innehåll

Skickas som JSON i anropet. Okända fält nekas.

Fält att skicka: Skriv en anteckning
FältTypKrävsBeskrivning
companyIdstring (uuid)JaKrävsFöretaget som anteckningen ska ligga på.
titlestring eller nullNejRubrik (valfri), till exempel Möte online.
  • Högst 120 tecken.
bodystringJaKrävsAnteckningens text. Personnummer i texten maskeras.
  • 1 till 20 000 tecken.
contactIdstring (uuid) eller nullNejKontakten som anteckningen gäller (valfri). Ska vara en av företagets kontakter.

Exempel på anrop

curl -X POST "/api/v1/notes" \
  -H "Authorization: Bearer $CRMDATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
  "title": "Möte online",
  "body": "Gick igenom offerten med Anna. De vill ha ett pris på tre år i stället för två och återkommer efter styrelsemötet i november.",
  "contactId": "7c1d2e3f-4a5b-4c6d-8e9f-0a1b2c3d4e5f"
}'

Svar

201SkapatSkapat. Location har adressen till det som skapades.

Exempel på svar

{
  "id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
  "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
  "contactId": "7c1d2e3f-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
  "title": "Möte online",
  "body": "Gick igenom offerten med Anna. De vill ha ett pris på tre år i stället för två och återkommer efter styrelsemötet i november.",
  "createdBy": null,
  "createdAt": "2026-10-05T12:00:00.000Z",
  "updatedAt": "2026-10-05T12:00:00.000Z"
}

Fälten i svaret (Note) är samma som i Lista anteckningar.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Hämta en anteckning

Nyckel: Läsa

GET/api/v1/notes/{id}

En anteckning med hela sin text.

Parametrar

Parametrar: Hämta en anteckning
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsId (uuid).

Exempel på anrop

curl "/api/v1/notes/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

200OKDet gick bra.

Exempel på svar

{
  "id": "9a8b7c6d-5e4f-4a3b-8c2d-1e0f9a8b7c6d",
  "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
  "contactId": "7c1d2e3f-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
  "title": "Möte online",
  "body": "Gick igenom offerten med Anna. De vill ha ett pris på tre år i stället för två och återkommer efter styrelsemötet i november.",
  "createdBy": null,
  "createdAt": "2026-10-05T12:00:00.000Z",
  "updatedAt": "2026-10-05T12:00:00.000Z"
}

Fälten i svaret (Note) är samma som i Lista anteckningar.

Fel som kan komma400401403404429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Radera en anteckning

Nyckel: Läsa och skriva

DELETE/api/v1/notes/{id}

Raderar anteckningen för gott, också ur företagets tidslinje. Det går inte att ångra.

Parametrar

Parametrar: Radera en anteckning
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsId (uuid).

Exempel på anrop

curl -X DELETE "/api/v1/notes/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

204Inget innehållDet gick bra. Svaret har inget innehåll.

Svaret har inget innehåll.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Händelser

Tidslinjen på ett företag: samtal, möten, mejl och annat som har hänt.

Lista händelser (tidslinjen)

Nyckel: Läsa

GET/api/v1/activities

Tidslinjen: allt som har hänt på organisationens sparade företag, det senaste först. Med companyId: tidslinjen för det företaget, som på kundkortet i appen. Med type: bara en sorts händelse. Listan sorteras på när det hände (occurredAt). Händelser går inte att ändra eller ta bort, så för stegvis synk räcker det att hämta det som lagts till: sort=createdAt&order=asc&updatedSince=<tidpunkt>. Mejl och möten som hämtats från Outlook visas inte i API:t.

Parametrar

Parametrar: Lista händelser (tidslinjen)
NamnPlatsTypKrävsBeskrivning
limitFrågeparameterintegerNejAntal rader per sida, 1 till 200. Standard 50.
  • 1 till 200.
  • Standard:50
cursorFrågeparameterstringNejVärdet i nextCursor från förra svaret, för att hämta nästa sida. Utelämnas för första sidan.
  • 1 till 400 tecken.
sortFrågeparameterstringNejSortering: occurredAt eller createdAt. Standard occurredAt.
  • Värden:occurredAtcreatedAt
  • Standard:occurredAt
orderFrågeparameterstringNejOrdning: desc (nyast först, standard) eller asc (äldst först).
  • Värden:ascdesc
  • Standard:desc
updatedSinceFrågeparameterstring (tidpunkt)NejBara händelser som sparats i CRM:et efter den här tidpunkten (createdAt). För stegvis synk: sort=createdAt&order=asc&updatedSince=…
companyIdFrågeparameterstring (uuid)NejBara händelser på det här företaget.
typeFrågeparameterstringNejBara händelser av den här typen. call = samtal, email_in = mejl in, email_out = mejl ut, meeting = möte, note = anteckning, task_completed = avslutad uppgift, deal_created = ny affär, deal_stage_changed = affär flyttad till ett annat steg, deal_won = vunnen affär, deal_lost = förlorad affär, order_event = något hände med en order, company_saved = företaget sparades, contact_added = ny kontakt, file_uploaded = uppladdad fil, master_update = nya uppgifter från företagsdatan, call_list_status = ny status i en ringlista.
  • Värden:callemail_inemail_outmeetingnotetask_completeddeal_createddeal_stage_changeddeal_wondeal_lostorder_eventcompany_savedcontact_addedfile_uploadedmaster_updatecall_list_status

Exempel på anrop

curl "/api/v1/activities" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

200OKDet gick bra.

Exempel på svar

{
  "data": [
    {
      "id": "4b3c2d1e-0f9a-4b8c-9d7e-6f5a4b3c2d1e",
      "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
      "contactId": "7c1d2e3f-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
      "dealId": null,
      "type": "call",
      "occurredAt": "2026-10-05T12:00:00.000Z",
      "summary": "Samtal: Uppföljning av offerten – Anna återkommer efter styrelsemötet i november",
      "actorUserId": null,
      "refType": null,
      "refId": null,
      "createdAt": "2026-10-05T12:00:00.000Z"
    }
  ],
  "nextCursor": null
}
Fälten i svaret (13): Activity
Fält i svaret: Lista händelser (tidslinjen)
FältTypBeskrivning
dataActivity[]Raderna på den här sidan.
data: idBara läsastring (uuid)Id (uuid).
data: companyIdstring (uuid)Företaget som händelsen hör till.
data: contactIdstring (uuid) eller nullKontakten som händelsen gäller. null om ingen är utpekad.
data: dealIdBara läsastring (uuid) eller nullAffären som händelsen gäller. null om den inte gäller en affär.
data: typestringVad som hände. call = samtal, email_in = mejl in, email_out = mejl ut, meeting = möte, note = anteckning, task_completed = avslutad uppgift, deal_created = ny affär, deal_stage_changed = affär flyttad till ett annat steg, deal_won = vunnen affär, deal_lost = förlorad affär, order_event = något hände med en order, company_saved = företaget sparades, contact_added = ny kontakt, file_uploaded = uppladdad fil, master_update = nya uppgifter från företagsdatan, call_list_status = ny status i en ringlista. Samtal, möten och mejl räknas som kontakt med företaget.
  • Värden:callemail_inemail_outmeetingnotetask_completeddeal_createddeal_stage_changeddeal_wondeal_lostorder_eventcompany_savedcontact_addedfile_uploadedmaster_updatecall_list_status
data: occurredAtBara läsastring (tidpunkt)När det hände.
data: summarystringHändelsen som text, så som den står i tidslinjen i appen.
data: actorUserIdBara läsastring eller nullAnvändaren som gjorde det. null när det gjordes via API:t eller av systemet.
data: refTypeBara läsastring eller nullVad refId pekar på: note = anteckning, task = uppgift, deal = affär, order = order, contact = kontakt, call_list_item = rad i en ringlista. null när händelsen inte pekar på något.
  • Värden:notetaskdealordercontactcall_list_item
data: refIdBara läsastring (uuid) eller nullId för det händelsen pekar på, till exempel anteckningen för en händelse av typen note. null när refType är null.
data: createdAtBara läsastring (tidpunkt)När händelsen sparades i CRM:et. Skiljer sig från occurredAt för sådant som förts in i efterhand.
nextCursorstring eller nullSkicka som cursor för att hämta nästa sida. null när det inte finns fler rader.

Bara läsa: fältet finns i svaren men går inte att skicka in.

Fel som kan komma400401403429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Logga ett samtal, möte eller mejl

Nyckel: Läsa och skriva

POST/api/v1/activities

Loggar en kontakt med ett sparat företag, precis som Logga kontakt i appen: ett samtal, ett möte eller ett mejl. Händelsen får tiden nu (det går inte att logga i efterhand med en annan tid) och hamnar i företagets tidslinje, och företagets senaste kontakt sätts till nu. Texten i tidslinjen sätts ihop av typen, rubriken och sammanfattningen. Annat i tidslinjen skapas av det som görs i CRM:et: en anteckning skrivs med POST /notes.

Parametrar

Parametrar: Logga ett samtal, möte eller mejl
NamnPlatsTypKrävsBeskrivning
Idempotency-KeyHuvudstringNejGör anropet säkert att skicka igen: samma nyckel och samma innehåll inom 24 timmar ger samma svar utan att något skapas två gånger. Till exempel ett uuid.
  • 1 till 200 tecken.

Innehåll

Skickas som JSON i anropet. Okända fält nekas.

Fält att skicka: Logga ett samtal, möte eller mejl
FältTypKrävsBeskrivning
companyIdstring (uuid)JaKrävsFöretaget som kontakten togs med.
typestringJaKrävsVad som loggas: call = samtal, meeting = möte, email_out = mejl som ni har skickat, email_in = mejl som ni har fått.
  • Värden:callemail_outemail_inmeeting
titlestring eller nullNejRubrik (valfri), till exempel Uppföljning av offerten.
  • Högst 120 tecken.
summarystring eller nullNejKort sammanfattning (valfri). Personnummer i texten maskeras.
  • Högst 2 000 tecken.
contactIdstring (uuid) eller nullNejKontakten som det gäller (valfri). Ska vara en av företagets kontakter.

Exempel på anrop

curl -X POST "/api/v1/activities" \
  -H "Authorization: Bearer $CRMDATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
  "type": "call",
  "title": "Uppföljning av offerten",
  "summary": "Anna återkommer efter styrelsemötet i november",
  "contactId": "7c1d2e3f-4a5b-4c6d-8e9f-0a1b2c3d4e5f"
}'

Svar

201SkapatSkapat.

Exempel på svar

{
  "id": "4b3c2d1e-0f9a-4b8c-9d7e-6f5a4b3c2d1e",
  "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
  "contactId": "7c1d2e3f-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
  "dealId": null,
  "type": "call",
  "occurredAt": "2026-10-05T12:00:00.000Z",
  "summary": "Samtal: Uppföljning av offerten – Anna återkommer efter styrelsemötet i november",
  "actorUserId": null,
  "refType": null,
  "refId": null,
  "createdAt": "2026-10-05T12:00:00.000Z"
}

Fälten i svaret (Activity) är samma som i Lista händelser (tidslinjen).

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Uppgifter

Uppgifter och påminnelser, med ansvarig och datum.

Lista uppgifter

Nyckel: Läsa

GET/api/v1/tasks

Organisationens uppgifter, nyast först. Alla uppgifter visas, oavsett ansvarig och status. Filtren går att kombinera: till exempel status=open och dueBefore för det som är försenat. Med sort=dueAt&order=asc kommer det som ska göras först överst. För stegvis synk: sort=updatedAt&order=asc&updatedSince=<tidpunkt>.

Parametrar

Parametrar: Lista uppgifter
NamnPlatsTypKrävsBeskrivning
limitFrågeparameterintegerNejAntal rader per sida, 1 till 200. Standard 50.
  • 1 till 200.
  • Standard:50
cursorFrågeparameterstringNejVärdet i nextCursor från förra svaret, för att hämta nästa sida. Utelämnas för första sidan.
  • 1 till 400 tecken.
sortFrågeparameterstringNejSortering: createdAt eller updatedAt eller dueAt. Standard createdAt.
  • Värden:createdAtupdatedAtdueAt
  • Standard:createdAt
orderFrågeparameterstringNejOrdning: desc (nyast först, standard) eller asc (äldst först).
  • Värden:ascdesc
  • Standard:desc
updatedSinceFrågeparameterstring (tidpunkt)NejBara det som ändrats efter den här tidpunkten: rader med updatedAt senare än den, räknat i millisekunder (raden med exakt samma updatedAt som ni skickar kommer inte med igen). För stegvis synk: sort=updatedAt&order=asc&updatedSince=<senaste updatedAt ni fått>.
companyIdFrågeparameterstring (uuid)NejBara uppgifter på det här företaget.
assignedToFrågeparameterstringNejBara uppgifter med den här ansvariga användaren.
  • 1 till 64 tecken.
statusFrågeparameterstringNejBara uppgifter med den här statusen: open (ska göras), done (klar) eller cancelled (struken).
  • Värden:opendonecancelled
dueBeforeFrågeparameterstring (tidpunkt)NejBara uppgifter som ska vara gjorda före den här tidpunkten.
dueAfterFrågeparameterstring (tidpunkt)NejBara uppgifter som ska vara gjorda vid eller efter den här tidpunkten.

Exempel på anrop

curl "/api/v1/tasks" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

200OKDet gick bra.

Exempel på svar

{
  "data": [
    {
      "id": "b4e1c2d3-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
      "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
      "contactId": null,
      "type": "call",
      "title": "Ring Anna om offerten",
      "description": "Hon ville ha besked före månadsskiftet.",
      "dueAt": "2026-10-12T07:00:00.000Z",
      "assignedTo": "Xk3mPq8RtV2wYz5aBc7dEf9gHj1LnN4s",
      "status": "open",
      "completedAt": null,
      "createdBy": null,
      "createdAt": "2026-10-05T08:15:00.000Z",
      "updatedAt": "2026-10-05T08:15:00.000Z"
    }
  ],
  "nextCursor": null
}
Fälten i svaret (15): Task
Fält i svaret: Lista uppgifter
FältTypBeskrivning
dataTask[]Raderna på den här sidan.
data: idBara läsastring (uuid)Uppgiftens id.
data: companyIdSätts när det skapasstring (uuid) eller nullFöretaget som uppgiften hör till. null för en äldre uppgift utan företag.
data: contactIdSätts när det skapasstring (uuid) eller nullKontaktpersonen på företaget som uppgiften gäller. null om ingen är vald.
data: typestringVilken sorts uppgift det är: call = ring, email = mejla, meeting = möte, other = övrigt.
  • Värden:callemailmeetingother
data: titlestringUppgiftens rubrik.
data: descriptionstring eller nullBeskrivning. null om uppgiften saknar beskrivning.
data: dueAtstring (tidpunkt)När uppgiften ska vara gjord.
data: assignedToSätts när det skapasstring eller nullAnsvarig användare. null om uppgiften saknar ansvarig. Användarna hämtas med GET /users.
data: statusstringopen = ska göras, done = klar, cancelled = struken.
  • Värden:opendonecancelled
data: completedAtBara läsastring (tidpunkt) eller nullNär uppgiften klarmarkerades. null så länge den inte är klar.
data: createdByBara läsastring eller nullAnvändaren som skapade uppgiften. null när den skapades via API:t eller av systemet.
data: createdAtBara läsastring (tidpunkt)När uppgiften skapades.
data: updatedAtBara läsastring (tidpunkt)När uppgiften senast ändrades.
nextCursorstring eller nullSkicka som cursor för att hämta nästa sida. null när det inte finns fler rader.

Bara läsa: fältet finns i svaren men går inte att skicka in.

Sätts när det skapas: fältet anges när objektet skapas (POST) och går sedan inte att ändra.

Fel som kan komma400401403429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Skapa en uppgift

Nyckel: Läsa och skriva

POST/api/v1/tasks

Skapar en uppgift på ett sparat företag, precis som Ny uppgift på kundkortet i appen. Uppgiften syns på kundkortet och i den ansvarigas att göra-lista. Ett möte (type meeting) läggs inte i någons Outlook-kalender via API:t: det görs i appen.

Parametrar

Parametrar: Skapa en uppgift
NamnPlatsTypKrävsBeskrivning
Idempotency-KeyHuvudstringNejGör anropet säkert att skicka igen: samma nyckel och samma innehåll inom 24 timmar ger samma svar utan att något skapas två gånger. Till exempel ett uuid.
  • 1 till 200 tecken.

Innehåll

Skickas som JSON i anropet. Okända fält nekas.

Fält att skicka: Skapa en uppgift
FältTypKrävsBeskrivning
companyIdstring (uuid)JaKrävsFöretaget som uppgiften ska ligga på.
typestringJaKrävsVilken sorts uppgift det är: call = ring, email = mejla, meeting = möte, other = övrigt.
  • Värden:callemailmeetingother
titlestringJaKrävsUppgiftens rubrik, högst 200 tecken. Personnummer i texten maskeras.
  • 1 till 200 tecken.
descriptionstring eller nullNejBeskrivning, högst 2000 tecken (valfri). Personnummer i texten maskeras.
  • Högst 2 000 tecken.
dueAtstring (tidpunkt)JaKrävsNär uppgiften ska vara gjord: tidpunkt med tidszon, till exempel 2026-10-12T09:00:00+02:00.
assignedTostring eller nullNejAnsvarig användare (id från GET /users). Utelämnat: uppgiften får ingen ansvarig och syns då på kundkortet, men inte i någons egen att göra-lista.
  • 1 till 64 tecken.
contactIdstring (uuid) eller nullNejEn kontaktperson på företaget som uppgiften gäller (valfri).

Exempel på anrop

curl -X POST "/api/v1/tasks" \
  -H "Authorization: Bearer $CRMDATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
  "type": "call",
  "title": "Ring Anna om offerten",
  "description": "Hon ville ha besked före månadsskiftet.",
  "dueAt": "2026-10-12T09:00:00+02:00",
  "assignedTo": "Xk3mPq8RtV2wYz5aBc7dEf9gHj1LnN4s"
}'

Svar

201SkapatSkapat. Location har adressen till det som skapades.

Exempel på svar

{
  "id": "b4e1c2d3-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
  "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
  "contactId": null,
  "type": "call",
  "title": "Ring Anna om offerten",
  "description": "Hon ville ha besked före månadsskiftet.",
  "dueAt": "2026-10-12T07:00:00.000Z",
  "assignedTo": "Xk3mPq8RtV2wYz5aBc7dEf9gHj1LnN4s",
  "status": "open",
  "completedAt": null,
  "createdBy": null,
  "createdAt": "2026-10-05T08:15:00.000Z",
  "updatedAt": "2026-10-05T08:15:00.000Z"
}

Fälten i svaret (Task) är samma som i Lista uppgifter.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Hämta en uppgift

Nyckel: Läsa

GET/api/v1/tasks/{id}

En uppgift.

Parametrar

Parametrar: Hämta en uppgift
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsId (uuid).

Exempel på anrop

curl "/api/v1/tasks/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

200OKDet gick bra.

Exempel på svar

{
  "id": "b4e1c2d3-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
  "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
  "contactId": null,
  "type": "call",
  "title": "Ring Anna om offerten",
  "description": "Hon ville ha besked före månadsskiftet.",
  "dueAt": "2026-10-12T07:00:00.000Z",
  "assignedTo": "Xk3mPq8RtV2wYz5aBc7dEf9gHj1LnN4s",
  "status": "open",
  "completedAt": null,
  "createdBy": null,
  "createdAt": "2026-10-05T08:15:00.000Z",
  "updatedAt": "2026-10-05T08:15:00.000Z"
}

Fälten i svaret (Task) är samma som i Lista uppgifter.

Fel som kan komma400401403404429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Ändra, skjut upp eller klarmarkera en uppgift

Nyckel: Läsa och skriva

PATCH/api/v1/tasks/{id}

Ändrar en uppgift. Skicka bara det som ska ändras; allt i anropet sparas tillsammans eller inte alls. Tre saker går att göra, var för sig eller i samma anrop. Ändra: type, title, description och dueAt. Skjuta upp, som Skjut upp i appen: postponeDays (så många dagar framåt, räknat från det senare av uppgiftens datum och i dag) eller postponeToDate (till ett visst datum, i dag eller senare). Klockslaget behålls, och dueAt anges inte samtidigt. Klarmarkera: status done. Då läggs en händelse i företagets tidslinje, och för ring, mejl och möte räknas det som en kontakt med företaget (senaste kontakt sätts till nu) om inte logContact är false. En uppgift som redan är klar går inte att ändra, skjuta upp eller klarmarkera igen (409), och den går inte att öppna på nytt. Ansvarig, företag och kontakt går inte att byta. Ligger uppgiften som ett möte i någons Outlook-kalender ändras kalendern inte via API:t.

Parametrar

Parametrar: Ändra, skjut upp eller klarmarkera en uppgift
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsId (uuid).

Innehåll

Skickas som JSON i anropet. Okända fält nekas.

Fält att skicka: Ändra, skjut upp eller klarmarkera en uppgift
FältTypKrävsBeskrivning
typestringNejVilken sorts uppgift det är: call = ring, email = mejla, meeting = möte, other = övrigt.
  • Värden:callemailmeetingother
titlestringNejNy rubrik, högst 200 tecken. Personnummer i texten maskeras.
  • 1 till 200 tecken.
descriptionstring eller nullNejNy beskrivning, högst 2000 tecken. null tar bort beskrivningen. Personnummer i texten maskeras.
  • Högst 2 000 tecken.
dueAtstring (tidpunkt)NejNy tidpunkt då uppgiften ska vara gjord, med tidszon. Går inte att ange tillsammans med postponeDays eller postponeToDate.
postponeDaysintegerNejSkjut upp så här många dagar (1 till 365), räknat från det senare av uppgiftens datum och i dag. Klockslaget behålls.
  • 1 till 365.
postponeToDatestring (datum)NejSkjut upp till det här datumet (ÅÅÅÅ-MM-DD), i dag eller senare. Klockslaget behålls.
statusstringNejdone klarmarkerar uppgiften. Inget annat värde går att sätta.
  • Alltid:done
logContactbooleanNejBara tillsammans med status done. true (standard): en klar uppgift av typen ring, mejl eller möte räknas som en kontakt med företaget. false: den räknas bara som en slutförd uppgift.

Exempel på anrop

curl -X PATCH "/api/v1/tasks/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a" \
  -H "Authorization: Bearer $CRMDATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "status": "done"
}'

Svar

200OKDet gick bra.

Exempel på svar

{
  "id": "b4e1c2d3-5f6a-4b7c-8d9e-0f1a2b3c4d5e",
  "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
  "contactId": null,
  "type": "call",
  "title": "Ring Anna om offerten",
  "description": "Hon ville ha besked före månadsskiftet.",
  "dueAt": "2026-10-12T07:00:00.000Z",
  "assignedTo": "Xk3mPq8RtV2wYz5aBc7dEf9gHj1LnN4s",
  "status": "done",
  "completedAt": "2026-10-12T08:05:00.000Z",
  "createdBy": null,
  "createdAt": "2026-10-05T08:15:00.000Z",
  "updatedAt": "2026-10-12T08:05:00.000Z"
}

Fälten i svaret (Task) är samma som i Lista uppgifter.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Affärer

Affärer i era pipelines, och pipelines med sina steg.

Lista affärer

Nyckel: Läsa

GET/api/v1/deals

Organisationens affärer, nyast först. Alla affärer visas, oavsett ansvarig, både pågående och avslutade. Filtren går att kombinera. För stegvis synk: sort=updatedAt&order=asc&updatedSince=<tidpunkt>.

Parametrar

Parametrar: Lista affärer
NamnPlatsTypKrävsBeskrivning
limitFrågeparameterintegerNejAntal rader per sida, 1 till 200. Standard 50.
  • 1 till 200.
  • Standard:50
cursorFrågeparameterstringNejVärdet i nextCursor från förra svaret, för att hämta nästa sida. Utelämnas för första sidan.
  • 1 till 400 tecken.
sortFrågeparameterstringNejSortering: createdAt eller updatedAt. Standard createdAt.
  • Värden:createdAtupdatedAt
  • Standard:createdAt
orderFrågeparameterstringNejOrdning: desc (nyast först, standard) eller asc (äldst först).
  • Värden:ascdesc
  • Standard:desc
updatedSinceFrågeparameterstring (tidpunkt)NejBara det som ändrats efter den här tidpunkten: rader med updatedAt senare än den, räknat i millisekunder (raden med exakt samma updatedAt som ni skickar kommer inte med igen). För stegvis synk: sort=updatedAt&order=asc&updatedSince=<senaste updatedAt ni fått>.
companyIdFrågeparameterstring (uuid)NejBara affärer på det här företaget.
pipelineIdFrågeparameterstring (uuid)NejBara affärer i den här pipelinen.
stageIdFrågeparameterstring (uuid)NejBara affärer i det här steget.
statusFrågeparameterstringNejBara affärer med den här statusen: open (pågår), won (vunnen) eller lost (förlorad).
  • Värden:openwonlost
ownerUserIdFrågeparameterstringNejBara affärer med den här ansvariga säljaren.
  • 1 till 64 tecken.

Exempel på anrop

curl "/api/v1/deals" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

200OKDet gick bra.

Exempel på svar

{
  "data": [
    {
      "id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
      "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
      "title": "Serviceavtal 2027",
      "valueSek": 185000,
      "pipelineId": "b1c2d3e4-f5a6-4b7c-8d9e-0f1a2b3c4d5e",
      "pipelineName": "Standard",
      "stageId": "c2d3e4f5-a6b7-4c8d-9e0f-1a2b3c4d5e6f",
      "stageName": "Offert",
      "status": "open",
      "ownerUserId": "Xk3mPq8RtV2wYz5aBc7dEf9gHj1LnN4s",
      "expectedCloseDate": "2026-11-30",
      "closedAt": null,
      "closeReason": null,
      "createdBy": null,
      "createdAt": "2026-10-05T08:15:00.000Z",
      "updatedAt": "2026-10-05T08:15:00.000Z"
    }
  ],
  "nextCursor": null
}
Fälten i svaret (18): Deal
Fält i svaret: Lista affärer
FältTypBeskrivning
dataDeal[]Raderna på den här sidan.
data: idBara läsastring (uuid)Affärens id.
data: companyIdSätts när det skapasstring (uuid)Företaget som affären hör till.
data: titlestringAffärens rubrik.
data: valueSeknumberAffärens värde i kronor, exklusive moms.
data: pipelineIdSätts när det skapasstring (uuid)Pipelinen som affären ligger i.
data: pipelineNameBara läsastringPipelinens namn.
data: stageIdstring (uuid)Steget som affären ligger i.
data: stageNameBara läsastringStegets namn, till exempel Offert.
data: statusBara läsastringopen = pågår, won = vunnen, lost = förlorad. Följer av steget: ändras genom att affären flyttas till ett annat steg.
  • Värden:openwonlost
data: ownerUserIdstring eller nullAnsvarig säljare. null om affären saknar ansvarig. Användarna hämtas med GET /users.
data: expectedCloseDatestring (datum) eller nullFörväntat avslut, ÅÅÅÅ-MM-DD. null om inget datum är satt.
data: closedAtBara läsastring (tidpunkt) eller nullNär affären blev vunnen eller förlorad. null så länge affären pågår.
data: closeReasonstring eller nullOrsaken till att affären förlorades, om någon angavs. null annars.
data: createdByBara läsastring eller nullAnvändaren som skapade affären. null när den skapades via API:t.
data: createdAtBara läsastring (tidpunkt)När affären skapades.
data: updatedAtBara läsastring (tidpunkt)När affären senast ändrades.
nextCursorstring eller nullSkicka som cursor för att hämta nästa sida. null när det inte finns fler rader.

Bara läsa: fältet finns i svaren men går inte att skicka in.

Sätts när det skapas: fältet anges när objektet skapas (POST) och går sedan inte att ändra.

Fel som kan komma400401403429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Skapa en affär

Nyckel: Läsa och skriva

POST/api/v1/deals

Skapar en affär på ett sparat företag, precis som Ny affär i appen: affären syns på pipelinetavlan och en händelse läggs i företagets tidslinje. Utan pipelineId hamnar affären i standardpipelinen, och utan stageId i pipelinens första steg (det öppna steget med lägst sannolikhet). Steget måste höra till pipelinen: för ett steg i en annan pipeline än standardpipelinen anges också pipelineId. Ett steg med utfallet vunnen eller förlorad ger en affär som är avslutad direkt. Pipelines och steg hämtas med GET /pipelines.

Parametrar

Parametrar: Skapa en affär
NamnPlatsTypKrävsBeskrivning
Idempotency-KeyHuvudstringNejGör anropet säkert att skicka igen: samma nyckel och samma innehåll inom 24 timmar ger samma svar utan att något skapas två gånger. Till exempel ett uuid.
  • 1 till 200 tecken.

Innehåll

Skickas som JSON i anropet. Okända fält nekas.

Fält att skicka: Skapa en affär
FältTypKrävsBeskrivning
companyIdstring (uuid)JaKrävsFöretaget som affären ska ligga på.
titlestringJaKrävsAffärens rubrik, högst 200 tecken. Personnummer i texten maskeras.
  • 1 till 200 tecken.
valueSeknumberNejAffärens värde i kronor, exklusive moms. Högst två decimaler. Utelämnat: 0.
  • Minst 0. Högst två decimaler.
expectedCloseDatestring (datum) eller nullNejFörväntat avslut, ÅÅÅÅ-MM-DD (valfritt).
pipelineIdstring (uuid) eller nullNejPipelinen som affären ska ligga i. Utelämnat: standardpipelinen.
stageIdstring (uuid) eller nullNejSteget som affären ska börja i. Utelämnat: pipelinens första steg, det öppna steget med lägst sannolikhet.
ownerUserIdstring eller nullNejAnsvarig säljare (id från GET /users). Utelämnat: affären får ingen ansvarig och syns då i appen bara för dem som ser allas affärer.
  • 1 till 64 tecken.

Exempel på anrop

curl -X POST "/api/v1/deals" \
  -H "Authorization: Bearer $CRMDATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
  "title": "Serviceavtal 2027",
  "valueSek": 185000,
  "expectedCloseDate": "2026-11-30",
  "ownerUserId": "Xk3mPq8RtV2wYz5aBc7dEf9gHj1LnN4s"
}'

Svar

201SkapatSkapat. Location har adressen till det som skapades.

Exempel på svar

{
  "id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
  "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
  "title": "Serviceavtal 2027",
  "valueSek": 185000,
  "pipelineId": "b1c2d3e4-f5a6-4b7c-8d9e-0f1a2b3c4d5e",
  "pipelineName": "Standard",
  "stageId": "c2d3e4f5-a6b7-4c8d-9e0f-1a2b3c4d5e6f",
  "stageName": "Offert",
  "status": "open",
  "ownerUserId": "Xk3mPq8RtV2wYz5aBc7dEf9gHj1LnN4s",
  "expectedCloseDate": "2026-11-30",
  "closedAt": null,
  "closeReason": null,
  "createdBy": null,
  "createdAt": "2026-10-05T08:15:00.000Z",
  "updatedAt": "2026-10-05T08:15:00.000Z"
}

Fälten i svaret (Deal) är samma som i Lista affärer.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Hämta en affär

Nyckel: Läsa

GET/api/v1/deals/{id}

En affär, med namnen på pipelinen och steget den ligger i.

Parametrar

Parametrar: Hämta en affär
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsId (uuid).

Exempel på anrop

curl "/api/v1/deals/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

200OKDet gick bra.

Exempel på svar

{
  "id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
  "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
  "title": "Serviceavtal 2027",
  "valueSek": 185000,
  "pipelineId": "b1c2d3e4-f5a6-4b7c-8d9e-0f1a2b3c4d5e",
  "pipelineName": "Standard",
  "stageId": "c2d3e4f5-a6b7-4c8d-9e0f-1a2b3c4d5e6f",
  "stageName": "Offert",
  "status": "open",
  "ownerUserId": "Xk3mPq8RtV2wYz5aBc7dEf9gHj1LnN4s",
  "expectedCloseDate": "2026-11-30",
  "closedAt": null,
  "closeReason": null,
  "createdBy": null,
  "createdAt": "2026-10-05T08:15:00.000Z",
  "updatedAt": "2026-10-05T08:15:00.000Z"
}

Fälten i svaret (Deal) är samma som i Lista affärer.

Fel som kan komma400401403404429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Ändra eller flytta en affär

Nyckel: Läsa och skriva

PATCH/api/v1/deals/{id}

Ändrar en affär. Skicka bara det som ska ändras; allt i anropet sparas tillsammans eller inte alls. Med stageId flyttas affären till ett annat steg i samma pipeline, precis som på pipelinetavlan: statusen följer av stegets utfall (vunnen, förlorad eller pågår igen), och en händelse läggs i företagets tidslinje. closeReason är orsaken när affären flyttas till ett steg med utfallet förlorad. Det går inte att ta bort ansvarig, byta företag eller byta pipeline, och status går inte att sätta direkt.

Parametrar

Parametrar: Ändra eller flytta en affär
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsId (uuid).

Innehåll

Skickas som JSON i anropet. Okända fält nekas.

Fält att skicka: Ändra eller flytta en affär
FältTypKrävsBeskrivning
titlestringNejNy rubrik, högst 200 tecken. Personnummer i texten maskeras.
  • 1 till 200 tecken.
valueSeknumberNejNytt värde i kronor, exklusive moms. Högst två decimaler.
  • Minst 0. Högst två decimaler.
expectedCloseDatestring (datum) eller nullNejFörväntat avslut, ÅÅÅÅ-MM-DD. null tar bort datumet.
ownerUserIdstringNejNy ansvarig säljare (id från GET /users). Ansvarig går inte att ta bort.
  • 1 till 64 tecken.
stageIdstring (uuid)NejSteget som affären ska flyttas till. Måste höra till affärens pipeline. Ligger affären redan där ändras ingenting.
closeReasonstringNejOrsaken till att affären förlorades, högst 500 tecken (valfri). Går bara att ange tillsammans med stageId, när affären flyttas till ett steg med utfallet förlorad.
  • 1 till 500 tecken.

Exempel på anrop

curl -X PATCH "/api/v1/deals/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a" \
  -H "Authorization: Bearer $CRMDATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "stageId": "e4f5a6b7-c8d9-4e0f-9a1b-2c3d4e5f6a7b",
  "closeReason": "Valde en annan leverantör"
}'

Svar

200OKDet gick bra.

Exempel på svar

{
  "id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
  "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
  "title": "Serviceavtal 2027",
  "valueSek": 185000,
  "pipelineId": "b1c2d3e4-f5a6-4b7c-8d9e-0f1a2b3c4d5e",
  "pipelineName": "Standard",
  "stageId": "e4f5a6b7-c8d9-4e0f-9a1b-2c3d4e5f6a7b",
  "stageName": "Förlorad",
  "status": "lost",
  "ownerUserId": "Xk3mPq8RtV2wYz5aBc7dEf9gHj1LnN4s",
  "expectedCloseDate": "2026-11-30",
  "closedAt": "2026-10-12T13:40:00.000Z",
  "closeReason": "Valde en annan leverantör",
  "createdBy": null,
  "createdAt": "2026-10-05T08:15:00.000Z",
  "updatedAt": "2026-10-12T13:40:00.000Z"
}

Fälten i svaret (Deal) är samma som i Lista affärer.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Lista pipelines med steg

Nyckel: Läsa

GET/api/v1/pipelines

Organisationens pipelines med sina steg i ordning. Stegen ordnas automatiskt: öppna steg efter sannolikhet (lägst först), sedan vunna och sist förlorade; det första steget är alltså det öppna steget med lägst sannolikhet. Använd stegens id som stageId när en affär skapas eller flyttas. Stegets utfall (outcome) avgör affärens status: flyttas en affär till ett steg med utfallet won blir den vunnen, och med lost förlorad. Alla pipelines kommer i ett svar (nextCursor är alltid null). Pipelines och steg ändras av en administratör i appen, inte via API:t.

Exempel på anrop

curl "/api/v1/pipelines" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

200OKDet gick bra.

Exempel på svar

{
  "data": [
    {
      "id": "b1c2d3e4-f5a6-4b7c-8d9e-0f1a2b3c4d5e",
      "name": "Standard",
      "isDefault": true,
      "stages": [
        {
          "id": "d1e2f3a4-b5c6-4d7e-8f9a-0b1c2d3e4f5a",
          "name": "Kontakt",
          "probability": 10,
          "outcome": "open"
        },
        {
          "id": "c2d3e4f5-a6b7-4c8d-9e0f-1a2b3c4d5e6f",
          "name": "Offert",
          "probability": 60,
          "outcome": "open"
        },
        {
          "id": "a3b4c5d6-e7f8-4a9b-8c0d-1e2f3a4b5c6d",
          "name": "Vunnen",
          "probability": 100,
          "outcome": "won"
        },
        {
          "id": "e4f5a6b7-c8d9-4e0f-9a1b-2c3d4e5f6a7b",
          "name": "Förlorad",
          "probability": 0,
          "outcome": "lost"
        }
      ]
    }
  ],
  "nextCursor": null
}
Fälten i svaret (10): Pipeline
Fält i svaret: Lista pipelines med steg
FältTypBeskrivning
dataPipeline[]Raderna på den här sidan.
data: idstring (uuid)Pipelinens id.
data: namestringPipelinens namn.
data: isDefaultbooleantrue för standardpipelinen: där hamnar en ny affär när pipelineId inte anges.
data: stagesPipelineStage[]Pipelinens steg, i den ordning de visas på pipelinetavlan i appen: öppna steg efter sannolikhet (lägst först), sedan steg med utfallet won och sist steg med utfallet lost.
data.stages: idstring (uuid)Stegets id. Anges som stageId när en affär skapas eller flyttas.
data.stages: namestringStegets namn, till exempel Offert.
data.stages: probabilityintegerSannolikheten i procent (0 till 100) att en affär i steget blir vunnen. Används för viktat värde i appen.
data.stages: outcomestringVad steget betyder för en affär som ligger där: open = pågår, won = vunnen, lost = förlorad. Affärens status följer stegets utfall.
  • Värden:openwonlost
nextCursorstring eller nullSkicka som cursor för att hämta nästa sida. null när det inte finns fler rader.
Fel som kan komma400401403429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Ordrar

Ordrar med rader. Att göra om en order till faktura och skicka den till Fortnox görs i appen.

Lista ordrar

Nyckel: Läsa

GET/api/v1/orders

Ordrarna i organisationen med sina rader, nyast först. Filtrera på företag, status eller säljare. För att följa vad som händer med fakturor och betalningar: hämta stegvis med sort=updatedAt&order=asc&updatedSince=<tidpunkt>.

Parametrar

Parametrar: Lista ordrar
NamnPlatsTypKrävsBeskrivning
limitFrågeparameterintegerNejAntal rader per sida, 1 till 200. Standard 50.
  • 1 till 200.
  • Standard:50
cursorFrågeparameterstringNejVärdet i nextCursor från förra svaret, för att hämta nästa sida. Utelämnas för första sidan.
  • 1 till 400 tecken.
sortFrågeparameterstringNejSortering: createdAt eller updatedAt. Standard createdAt.
  • Värden:createdAtupdatedAt
  • Standard:createdAt
orderFrågeparameterstringNejOrdning: desc (nyast först, standard) eller asc (äldst först).
  • Värden:ascdesc
  • Standard:desc
updatedSinceFrågeparameterstring (tidpunkt)NejBara det som ändrats efter den här tidpunkten: rader med updatedAt senare än den, räknat i millisekunder (raden med exakt samma updatedAt som ni skickar kommer inte med igen). För stegvis synk: sort=updatedAt&order=asc&updatedSince=<senaste updatedAt ni fått>.
companyIdFrågeparameterstring (uuid)NejBara ordrar på det här företaget.
statusFrågeparameterstringNejBara ordrar med den här statusen, till exempel order eller invoiced.
  • Värden:orderready_for_invoicesent_to_fortnoxfortnox_send_failedinvoicedpaidcreditedcancelled
ownerUserIdFrågeparameterstringNejBara ordrar med den här säljaren. Id hämtas med GET /users.
  • 1 till 64 tecken.

Exempel på anrop

curl "/api/v1/orders" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

200OKDet gick bra.

Exempel på svar

{
  "data": [
    {
      "id": "c7d8e9f0-1a2b-4c3d-9e4f-5a6b7c8d9e0f",
      "orderNumber": 1042,
      "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
      "status": "order",
      "editable": true,
      "orderDate": "2026-10-05",
      "ownerUserId": null,
      "ourReference": null,
      "customerReferenceContactId": "7c1d2e3f-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
      "customerReferenceText": "Inköpsorder 4471",
      "invoiceName": "Nordbygg Entreprenad AB",
      "invoiceStreet": "Box 1234",
      "invoicePostalCode": "751 42",
      "invoiceCity": "Uppsala",
      "invoiceEmail": "faktura@nordbygg.example",
      "paymentTermsDays": 30,
      "vatType": "SEVAT",
      "remark": "Avser serviceavtal 2027.",
      "subtotalSek": 16146,
      "vatSek": 4036.5,
      "roundingSek": 0.5,
      "totalSek": 20183,
      "rows": [
        {
          "id": "b3a2c1d0-9e8f-4a7b-8c6d-5e4f3a2b1c0d",
          "orderId": "c7d8e9f0-1a2b-4c3d-9e4f-5a6b7c8d9e0f",
          "productId": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
          "articleNumber": "1040",
          "description": "Serviceavtal Bas, per månad. Support vardagar 8–17.",
          "quantity": 12,
          "unit": "mån",
          "priceSek": 1495,
          "discountPercent": 10,
          "vatRate": 25,
          "totalSek": 16146
        }
      ],
      "readyAt": null,
      "sentAt": null,
      "invoicedAt": null,
      "paidAt": null,
      "fortnoxInvoiceNumber": null,
      "fortnoxTotalToPaySek": null,
      "fortnoxSyncedAt": null,
      "paymentStatus": null,
      "paymentDueDate": null,
      "paymentBalanceSek": null,
      "paymentOverdueDays": null,
      "createdBy": null,
      "createdAt": "2026-10-05T12:00:00.000Z",
      "updatedAt": "2026-10-05T12:00:00.000Z"
    }
  ],
  "nextCursor": null
}
Fälten i svaret (50): Order
Fält i svaret: Lista ordrar
FältTypBeskrivning
dataOrder[]Raderna på den här sidan.
data: idBara läsastring (uuid)Id (uuid).
data: orderNumberBara läsaintegerOrdernummer: löpnummer inom organisationen. Sätts av CRM:et.
data: companyIdSätts när det skapasstring (uuid)Företaget som ordern gäller.
data: statusBara läsastringVar ordern är i flödet: order (Order: går att ändra), ready_for_invoice (Klar för faktura: låst), sent_to_fortnox (Skickad till Fortnox), fortnox_send_failed (Kunde inte skickas), invoiced (Fakturerad), paid (Betald), credited (Krediterad) eller cancelled (Makulerad). Stegen efter order görs i appen.
  • Värden:orderready_for_invoicesent_to_fortnoxfortnox_send_failedinvoicedpaidcreditedcancelled
data: editableBara läsabooleantrue så länge ordern har status order. Då går uppgifter och rader att ändra; annars svarar API:t 409.
data: orderDatestring (datum)Orderdatum.
data: ownerUserIdBara läsastring eller nullSäljaren: användaren som skapade ordern i appen. null när ordern skapades via API:t.
data: ourReferencestring eller nullVår referens: namnet som står som er kontaktperson på fakturan.
data: customerReferenceContactIdstring (uuid) eller nullDeras referens: en kontakt på företaget. null om ingen är vald.
data: customerReferenceTextstring eller nullDeras referens som fri text. Används på fakturan när ingen kontakt är vald.
data: invoiceNamestring eller nullNamnet på fakturan.
data: invoiceStreetstring eller nullFakturaadress: gata eller box.
data: invoicePostalCodestring eller nullFakturaadress: postnummer.
data: invoiceCitystring eller nullFakturaadress: ort.
data: invoiceEmailstring eller nullE-postadressen som fakturan skickas till.
data: paymentTermsDaysintegerBetalvillkor i dagar.
data: vatTypestringMomstyp: SEVAT (svensk moms), SEREVERSEDVAT (omvänd skattskyldighet, bygg), EUREVERSEDVAT (EU, omvänd skattskyldighet), EUVAT (EU med moms) eller EXPORT. Med allt utom SEVAT blir momsen 0 på raderna.
  • Värden:SEVATSEREVERSEDVATEUREVERSEDVATEUVATEXPORT
data: remarkstring eller nullFakturatext: en rad text som skrivs på fakturan.
data: subtotalSekBara läsanumberSumma i kronor exklusive moms, efter rabatter. Räknas ut ur raderna.
data: vatSekBara läsanumberMoms i kronor. Räknas ut ur raderna.
data: roundingSekBara läsanumberÖresavrundning i kronor: det som läggs till eller dras av för att totalen ska bli hela kronor.
data: totalSekBara läsanumberAtt betala i kronor, inklusive moms, avrundat till hela kronor.
data: rowsOrderRow[]Orderns rader, i den ordning de står på ordern.
data.rows: idBara läsastring (uuid)Id (uuid).
data.rows: orderIdBara läsastring (uuid)Ordern som raden hör till.
data.rows: productIdSätts när det skapasstring (uuid) eller nullArtikeln som raden bygger på. null för en rad med fri text.
data.rows: articleNumberBara läsastring eller nullArtikelns artikelnummer, hämtat från artikeln. null för en rad utan artikel och för en artikel utan nummer. Går bara att läsa.
data.rows: descriptionstringRadens text, så som den står på ordern och fakturan.
data.rows: quantitynumberAntal, med högst två decimaler.
data.rows: unitBara läsastring eller nullArtikelns enhet, till exempel st eller tim. null för en rad utan artikel. Går bara att läsa.
data.rows: priceSeknumberPris per enhet i kronor, exklusive moms.
data.rows: discountPercentnumberRabatt i procent, 0 till 100.
data.rows: vatRatenumberRadens momssats i procent. Har ordern en annan momstyp än SEVAT räknas momsen som 0 på raden, oavsett vad som står här.
data.rows: totalSekBara läsanumberRadens summa i kronor efter rabatt, exklusive moms. Räknas ut av CRM:et.
data: readyAtBara läsastring (tidpunkt) eller nullNär ordern gjordes om till faktura i appen (Klar för faktura). null innan dess.
data: sentAtBara läsastring (tidpunkt) eller nullNär fakturan skickades till Fortnox. null innan dess.
data: invoicedAtBara läsastring (tidpunkt) eller nullNär fakturan bokfördes i Fortnox. null innan dess.
data: paidAtBara läsastring (tidpunkt) eller nullNär fakturan blev betald enligt Fortnox. null om den inte är betald.
data: fortnoxInvoiceNumberBara läsastring eller nullFakturanumret i Fortnox. null tills fakturan har skickats dit. Går bara att läsa.
data: fortnoxTotalToPaySekBara läsanumber eller nullAtt betala i kronor enligt Fortnox, som avrundar på sitt eget sätt. null tills status har hämtats från Fortnox. Går bara att läsa.
data: fortnoxSyncedAtBara läsastring (tidpunkt) eller nullNär status och betalning senast hämtades från Fortnox (sker automatiskt kl 06, 12 och 17). null om det aldrig har gjorts.
data: paymentStatusBara läsastring eller nullBetalningsläget enligt Fortnox, så som appen visar det: paid (Betald), due (obetald, förfallodagen har inte passerat) eller overdue (Försenad: obetald och förfallodagen har passerat). null när ordern inte är fakturerad, är krediterad eller makulerad, eller när Fortnox inte har gett någon förfallodag än.
  • Värden:paiddueoverdue
data: paymentDueDateBara läsastring (datum) eller nullFakturans förfallodag enligt Fortnox. null när den inte är känd.
data: paymentBalanceSekBara läsanumber eller nullKvar att betala i kronor enligt Fortnox. null när det inte är känt, och när fakturan är betald.
data: paymentOverdueDaysBara läsainteger eller nullAntal dagar sedan förfallodagen, när paymentStatus är overdue. Annars null.
data: createdByBara läsastring eller nullAnvändaren som skapade ordern. null när den skapades via API:t.
data: createdAtBara läsastring (tidpunkt)När ordern skapades.
data: updatedAtBara läsastring (tidpunkt)När ordern senast ändrades. Ändras också när en rad läggs till, ändras eller tas bort.
nextCursorstring eller nullSkicka som cursor för att hämta nästa sida. null när det inte finns fler rader.

Bara läsa: fältet finns i svaren men går inte att skicka in.

Sätts när det skapas: fältet anges när objektet skapas (POST) och går sedan inte att ändra.

Fel som kan komma400401403429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Skapa en order

Nyckel: Läsa och skriva

POST/api/v1/orders

Skapar en order på ett sparat företag, som knappen Skapa order på kundkortet. Fakturauppgifter och betalvillkor kopieras från företaget och företagets huvudkontakt blir deras referens, om inget annat anges. Raderna kan skickas med direkt (rows): då sparas ordern och alla rader, eller ingenting om något är fel. Ordern får nästa ordernummer, status order och ingen säljare, och i appen syns den för dem som får se allas ordrar. En händelse skrivs i företagets tidslinje. Det går inte att skapa en order på ett företag som är märkt Kontakta inte.

Parametrar

Parametrar: Skapa en order
NamnPlatsTypKrävsBeskrivning
Idempotency-KeyHuvudstringNejGör anropet säkert att skicka igen: samma nyckel och samma innehåll inom 24 timmar ger samma svar utan att något skapas två gånger. Till exempel ett uuid.
  • 1 till 200 tecken.

Innehåll

Skickas som JSON i anropet. Okända fält nekas.

Fält att skicka: Skapa en order
FältTypKrävsBeskrivning
companyIdstring (uuid)JaKrävsFöretaget som ordern gäller. Ska vara ett av era sparade företag.
orderDatestring (datum)NejOrderdatum. Utelämnat när ordern skapas: dagens datum.
ourReferencestring eller nullNejVår referens, högst 100 tecken. Tom på en order som skapas via API:t; när fakturan skickas till Fortnox står då avsändaren som referens.
  • Högst 100 tecken.
customerReferenceContactIdstring (uuid) eller nullNejDeras referens: en av företagets kontakter. Utelämnat när ordern skapas: företagets huvudkontakt. null = ingen kontakt.
customerReferenceTextstring eller nullNejDeras referens som fri text, högst 100 tecken.
  • Högst 100 tecken.
invoiceNamestring eller nullNejNamnet på fakturan, högst 200 tecken. Utelämnat när ordern skapas: företagets fakturanamn, annars företagets namn.
  • Högst 200 tecken.
invoiceStreetstring eller nullNejFakturaadress: gata eller box, högst 200 tecken. Utelämnat när ordern skapas: företagets fakturaadress, annars besöksadressen.
  • Högst 200 tecken.
invoicePostalCodestring eller nullNejFakturaadress: postnummer, högst 20 tecken. Utelämnat när ordern skapas: från företaget.
  • Högst 20 tecken.
invoiceCitystring eller nullNejFakturaadress: ort, högst 100 tecken. Utelämnat när ordern skapas: från företaget.
  • Högst 100 tecken.
invoiceEmailstring eller nullNejE-postadressen som fakturan skickas till, högst 200 tecken. Utelämnat när ordern skapas: företagets e-post för fakturor, annars företagets e-post.
  • Högst 200 tecken.
paymentTermsDaysintegerNejBetalvillkor i hela dagar, 0 till 120. Utelämnat när ordern skapas: företagets betalvillkor, annars 30.
  • 0 till 120.
vatTypestringNejMomstyp: SEVAT (svensk moms, standard), SEREVERSEDVAT, EUREVERSEDVAT, EUVAT eller EXPORT. Med allt utom SEVAT blir momsen 0 på raderna.
  • Värden:SEVATSEREVERSEDVATEUREVERSEDVATEUVATEXPORT
remarkstring eller nullNejFakturatext, högst 1000 tecken.
  • Högst 1 000 tecken.
rowsobject[]NejOrderns rader, i den ordning de ska stå. Högst 100 i ett anrop; fler läggs till med POST /orders/{id}/rows.
  • Högst 100 värden.
rows: productIdstring (uuid) eller nullNejArtikeln som raden ska bygga på. Bara aktiva artiklar går att välja. Utelämnat eller null: en rad med fri text.
rows: descriptionstring eller nullNejRadens text, högst 300 tecken. Utelämnat med artikel: artikelns beskrivning, annars artikelns namn. Krävs för en rad utan artikel.
  • Högst 300 tecken.
rows: quantitynumberNejAntal, större än 0 och med högst två decimaler. Utelämnat: 1.
  • 0,01 till 1 000 000. Högst två decimaler.
rows: priceSeknumberNejPris per enhet i kronor, exklusive moms. Utelämnat: artikelns pris (0 för en rad utan artikel).
  • Minst 0. Högst två decimaler.
rows: discountPercentnumberNejRabatt i procent, 0 till 100. Utelämnat: 0.
  • 0 till 100. Högst två decimaler.
rows: vatRatenumberNejMomssats i procent, 0 till 100. Utelämnat: artikelns moms (25 för en rad utan artikel).
  • 0 till 100. Högst två decimaler.

Exempel på anrop

curl -X POST "/api/v1/orders" \
  -H "Authorization: Bearer $CRMDATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
  "customerReferenceText": "Inköpsorder 4471",
  "remark": "Avser serviceavtal 2027.",
  "rows": [
    {
      "productId": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
      "quantity": 12,
      "discountPercent": 10
    }
  ]
}'

Svar

201SkapatSkapat. Location har adressen till det som skapades.

Exempel på svar

{
  "id": "c7d8e9f0-1a2b-4c3d-9e4f-5a6b7c8d9e0f",
  "orderNumber": 1042,
  "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
  "status": "order",
  "editable": true,
  "orderDate": "2026-10-05",
  "ownerUserId": null,
  "ourReference": null,
  "customerReferenceContactId": "7c1d2e3f-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
  "customerReferenceText": "Inköpsorder 4471",
  "invoiceName": "Nordbygg Entreprenad AB",
  "invoiceStreet": "Box 1234",
  "invoicePostalCode": "751 42",
  "invoiceCity": "Uppsala",
  "invoiceEmail": "faktura@nordbygg.example",
  "paymentTermsDays": 30,
  "vatType": "SEVAT",
  "remark": "Avser serviceavtal 2027.",
  "subtotalSek": 16146,
  "vatSek": 4036.5,
  "roundingSek": 0.5,
  "totalSek": 20183,
  "rows": [
    {
      "id": "b3a2c1d0-9e8f-4a7b-8c6d-5e4f3a2b1c0d",
      "orderId": "c7d8e9f0-1a2b-4c3d-9e4f-5a6b7c8d9e0f",
      "productId": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
      "articleNumber": "1040",
      "description": "Serviceavtal Bas, per månad. Support vardagar 8–17.",
      "quantity": 12,
      "unit": "mån",
      "priceSek": 1495,
      "discountPercent": 10,
      "vatRate": 25,
      "totalSek": 16146
    }
  ],
  "readyAt": null,
  "sentAt": null,
  "invoicedAt": null,
  "paidAt": null,
  "fortnoxInvoiceNumber": null,
  "fortnoxTotalToPaySek": null,
  "fortnoxSyncedAt": null,
  "paymentStatus": null,
  "paymentDueDate": null,
  "paymentBalanceSek": null,
  "paymentOverdueDays": null,
  "createdBy": null,
  "createdAt": "2026-10-05T12:00:00.000Z",
  "updatedAt": "2026-10-05T12:00:00.000Z"
}

Fälten i svaret (Order) är samma som i Lista ordrar.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Hämta en order

Nyckel: Läsa

GET/api/v1/orders/{id}

En order med rader, summor, status och betalningsläge. Fakturanummer och betalning visas så som de senast hämtades från Fortnox.

Parametrar

Parametrar: Hämta en order
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsId (uuid).

Exempel på anrop

curl "/api/v1/orders/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

200OKDet gick bra.

Exempel på svar

{
  "id": "c7d8e9f0-1a2b-4c3d-9e4f-5a6b7c8d9e0f",
  "orderNumber": 1042,
  "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
  "status": "order",
  "editable": true,
  "orderDate": "2026-10-05",
  "ownerUserId": null,
  "ourReference": null,
  "customerReferenceContactId": "7c1d2e3f-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
  "customerReferenceText": "Inköpsorder 4471",
  "invoiceName": "Nordbygg Entreprenad AB",
  "invoiceStreet": "Box 1234",
  "invoicePostalCode": "751 42",
  "invoiceCity": "Uppsala",
  "invoiceEmail": "faktura@nordbygg.example",
  "paymentTermsDays": 30,
  "vatType": "SEVAT",
  "remark": "Avser serviceavtal 2027.",
  "subtotalSek": 16146,
  "vatSek": 4036.5,
  "roundingSek": 0.5,
  "totalSek": 20183,
  "rows": [
    {
      "id": "b3a2c1d0-9e8f-4a7b-8c6d-5e4f3a2b1c0d",
      "orderId": "c7d8e9f0-1a2b-4c3d-9e4f-5a6b7c8d9e0f",
      "productId": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
      "articleNumber": "1040",
      "description": "Serviceavtal Bas, per månad. Support vardagar 8–17.",
      "quantity": 12,
      "unit": "mån",
      "priceSek": 1495,
      "discountPercent": 10,
      "vatRate": 25,
      "totalSek": 16146
    }
  ],
  "readyAt": null,
  "sentAt": null,
  "invoicedAt": null,
  "paidAt": null,
  "fortnoxInvoiceNumber": null,
  "fortnoxTotalToPaySek": null,
  "fortnoxSyncedAt": null,
  "paymentStatus": null,
  "paymentDueDate": null,
  "paymentBalanceSek": null,
  "paymentOverdueDays": null,
  "createdBy": null,
  "createdAt": "2026-10-05T12:00:00.000Z",
  "updatedAt": "2026-10-05T12:00:00.000Z"
}

Fälten i svaret (Order) är samma som i Lista ordrar.

Fel som kan komma400401403404429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Ändra en order

Nyckel: Läsa och skriva

PATCH/api/v1/orders/{id}

Ändrar orderns uppgifter: datum, referenser, fakturauppgifter, betalvillkor, momstyp och fakturatext. Fält som inte skickas lämnas orörda och null tömmer fältet. Går bara så länge ordern har status order: därefter är den låst och API:t svarar 409. Företag, säljare och status går inte att ändra här; rader ändras med slutpunkterna under /orders/{id}/rows.

Parametrar

Parametrar: Ändra en order
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsId (uuid).

Innehåll

Skickas som JSON i anropet. Okända fält nekas.

Fält att skicka: Ändra en order
FältTypKrävsBeskrivning
orderDatestring (datum)NejOrderdatum. Utelämnat när ordern skapas: dagens datum.
ourReferencestring eller nullNejVår referens, högst 100 tecken. Tom på en order som skapas via API:t; när fakturan skickas till Fortnox står då avsändaren som referens.
  • Högst 100 tecken.
customerReferenceContactIdstring (uuid) eller nullNejDeras referens: en av företagets kontakter. Utelämnat när ordern skapas: företagets huvudkontakt. null = ingen kontakt.
customerReferenceTextstring eller nullNejDeras referens som fri text, högst 100 tecken.
  • Högst 100 tecken.
invoiceNamestring eller nullNejNamnet på fakturan, högst 200 tecken. Utelämnat när ordern skapas: företagets fakturanamn, annars företagets namn.
  • Högst 200 tecken.
invoiceStreetstring eller nullNejFakturaadress: gata eller box, högst 200 tecken. Utelämnat när ordern skapas: företagets fakturaadress, annars besöksadressen.
  • Högst 200 tecken.
invoicePostalCodestring eller nullNejFakturaadress: postnummer, högst 20 tecken. Utelämnat när ordern skapas: från företaget.
  • Högst 20 tecken.
invoiceCitystring eller nullNejFakturaadress: ort, högst 100 tecken. Utelämnat när ordern skapas: från företaget.
  • Högst 100 tecken.
invoiceEmailstring eller nullNejE-postadressen som fakturan skickas till, högst 200 tecken. Utelämnat när ordern skapas: företagets e-post för fakturor, annars företagets e-post.
  • Högst 200 tecken.
paymentTermsDaysintegerNejBetalvillkor i hela dagar, 0 till 120. Utelämnat när ordern skapas: företagets betalvillkor, annars 30.
  • 0 till 120.
vatTypestringNejMomstyp: SEVAT (svensk moms, standard), SEREVERSEDVAT, EUREVERSEDVAT, EUVAT eller EXPORT. Med allt utom SEVAT blir momsen 0 på raderna.
  • Värden:SEVATSEREVERSEDVATEUREVERSEDVATEUVATEXPORT
remarkstring eller nullNejFakturatext, högst 1000 tecken.
  • Högst 1 000 tecken.

Exempel på anrop

curl -X PATCH "/api/v1/orders/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a" \
  -H "Authorization: Bearer $CRMDATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "paymentTermsDays": 20,
  "invoiceEmail": "faktura@nordbygg.example",
  "remark": null
}'

Svar

200OKDet gick bra.

Exempel på svar

{
  "id": "c7d8e9f0-1a2b-4c3d-9e4f-5a6b7c8d9e0f",
  "orderNumber": 1042,
  "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
  "status": "order",
  "editable": true,
  "orderDate": "2026-10-05",
  "ownerUserId": null,
  "ourReference": null,
  "customerReferenceContactId": "7c1d2e3f-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
  "customerReferenceText": "Inköpsorder 4471",
  "invoiceName": "Nordbygg Entreprenad AB",
  "invoiceStreet": "Box 1234",
  "invoicePostalCode": "751 42",
  "invoiceCity": "Uppsala",
  "invoiceEmail": "faktura@nordbygg.example",
  "paymentTermsDays": 20,
  "vatType": "SEVAT",
  "remark": null,
  "subtotalSek": 16146,
  "vatSek": 4036.5,
  "roundingSek": 0.5,
  "totalSek": 20183,
  "rows": [
    {
      "id": "b3a2c1d0-9e8f-4a7b-8c6d-5e4f3a2b1c0d",
      "orderId": "c7d8e9f0-1a2b-4c3d-9e4f-5a6b7c8d9e0f",
      "productId": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
      "articleNumber": "1040",
      "description": "Serviceavtal Bas, per månad. Support vardagar 8–17.",
      "quantity": 12,
      "unit": "mån",
      "priceSek": 1495,
      "discountPercent": 10,
      "vatRate": 25,
      "totalSek": 16146
    }
  ],
  "readyAt": null,
  "sentAt": null,
  "invoicedAt": null,
  "paidAt": null,
  "fortnoxInvoiceNumber": null,
  "fortnoxTotalToPaySek": null,
  "fortnoxSyncedAt": null,
  "paymentStatus": null,
  "paymentDueDate": null,
  "paymentBalanceSek": null,
  "paymentOverdueDays": null,
  "createdBy": null,
  "createdAt": "2026-10-05T12:00:00.000Z",
  "updatedAt": "2026-10-06T08:30:00.000Z"
}

Fälten i svaret (Order) är samma som i Lista ordrar.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Lägg till en orderrad

Nyckel: Läsa och skriva

POST/api/v1/orders/{id}/rows

Lägger en rad sist på ordern, som Lägg till rad i appen. Med productId fylls text, pris och moms i från artikeln där de inte anges; utan artikel blir det en rad med fri text och då krävs description. Orderns summor räknas om: hämta ordern för att se dem. Går bara så länge ordern har status order (annars 409).

Parametrar

Parametrar: Lägg till en orderrad
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsOrderns id.
Idempotency-KeyHuvudstringNejGör anropet säkert att skicka igen: samma nyckel och samma innehåll inom 24 timmar ger samma svar utan att något skapas två gånger. Till exempel ett uuid.
  • 1 till 200 tecken.

Innehåll

Skickas som JSON i anropet. Okända fält nekas.

Fält att skicka: Lägg till en orderrad
FältTypKrävsBeskrivning
productIdstring (uuid) eller nullNejArtikeln som raden ska bygga på. Bara aktiva artiklar går att välja. Utelämnat eller null: en rad med fri text.
descriptionstring eller nullNejRadens text, högst 300 tecken. Utelämnat med artikel: artikelns beskrivning, annars artikelns namn. Krävs för en rad utan artikel.
  • Högst 300 tecken.
quantitynumberNejAntal, större än 0 och med högst två decimaler. Utelämnat: 1.
  • 0,01 till 1 000 000. Högst två decimaler.
priceSeknumberNejPris per enhet i kronor, exklusive moms. Utelämnat: artikelns pris (0 för en rad utan artikel).
  • Minst 0. Högst två decimaler.
discountPercentnumberNejRabatt i procent, 0 till 100. Utelämnat: 0.
  • 0 till 100. Högst två decimaler.
vatRatenumberNejMomssats i procent, 0 till 100. Utelämnat: artikelns moms (25 för en rad utan artikel).
  • 0 till 100. Högst två decimaler.

Exempel på anrop

curl -X POST "/api/v1/orders/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a/rows" \
  -H "Authorization: Bearer $CRMDATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "productId": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
  "quantity": 12,
  "discountPercent": 10
}'

Svar

201SkapatSkapat.

Exempel på svar

{
  "id": "b3a2c1d0-9e8f-4a7b-8c6d-5e4f3a2b1c0d",
  "orderId": "c7d8e9f0-1a2b-4c3d-9e4f-5a6b7c8d9e0f",
  "productId": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
  "articleNumber": "1040",
  "description": "Serviceavtal Bas, per månad. Support vardagar 8–17.",
  "quantity": 12,
  "unit": "mån",
  "priceSek": 1495,
  "discountPercent": 10,
  "vatRate": 25,
  "totalSek": 16146
}
Fälten i svaret (11): OrderRow
Fält i svaret: Lägg till en orderrad
FältTypBeskrivning
idBara läsastring (uuid)Id (uuid).
orderIdBara läsastring (uuid)Ordern som raden hör till.
productIdSätts när det skapasstring (uuid) eller nullArtikeln som raden bygger på. null för en rad med fri text.
articleNumberBara läsastring eller nullArtikelns artikelnummer, hämtat från artikeln. null för en rad utan artikel och för en artikel utan nummer. Går bara att läsa.
descriptionstringRadens text, så som den står på ordern och fakturan.
quantitynumberAntal, med högst två decimaler.
unitBara läsastring eller nullArtikelns enhet, till exempel st eller tim. null för en rad utan artikel. Går bara att läsa.
priceSeknumberPris per enhet i kronor, exklusive moms.
discountPercentnumberRabatt i procent, 0 till 100.
vatRatenumberRadens momssats i procent. Har ordern en annan momstyp än SEVAT räknas momsen som 0 på raden, oavsett vad som står här.
totalSekBara läsanumberRadens summa i kronor efter rabatt, exklusive moms. Räknas ut av CRM:et.

Bara läsa: fältet finns i svaren men går inte att skicka in.

Sätts när det skapas: fältet anges när objektet skapas (POST) och går sedan inte att ändra.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Ändra en orderrad

Nyckel: Läsa och skriva

PATCH/api/v1/orders/{id}/rows/{rowId}

Ändrar text, antal, pris, rabatt eller moms på en rad. Fält som inte skickas lämnas orörda. Artikeln på raden går inte att byta: ta bort raden och lägg till en ny. Orderns summor räknas om. Går bara så länge ordern har status order (annars 409).

Parametrar

Parametrar: Ändra en orderrad
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsOrderns id.
rowIdAdressenstring (uuid)JaKrävsRadens id.

Innehåll

Skickas som JSON i anropet. Okända fält nekas.

Fält att skicka: Ändra en orderrad
FältTypKrävsBeskrivning
descriptionstringNejRadens text, högst 300 tecken. Får inte vara tom.
  • 1 till 300 tecken.
quantitynumberNejAntal, större än 0 och med högst två decimaler.
  • 0,01 till 1 000 000. Högst två decimaler.
priceSeknumberNejPris per enhet i kronor, exklusive moms.
  • Minst 0. Högst två decimaler.
discountPercentnumberNejRabatt i procent, 0 till 100.
  • 0 till 100. Högst två decimaler.
vatRatenumberNejMomssats i procent, 0 till 100.
  • 0 till 100. Högst två decimaler.

Exempel på anrop

curl -X PATCH "/api/v1/orders/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a/rows/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a" \
  -H "Authorization: Bearer $CRMDATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "quantity": 24,
  "discountPercent": 15
}'

Svar

200OKDet gick bra.

Exempel på svar

{
  "id": "b3a2c1d0-9e8f-4a7b-8c6d-5e4f3a2b1c0d",
  "orderId": "c7d8e9f0-1a2b-4c3d-9e4f-5a6b7c8d9e0f",
  "productId": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
  "articleNumber": "1040",
  "description": "Serviceavtal Bas, per månad. Support vardagar 8–17.",
  "quantity": 24,
  "unit": "mån",
  "priceSek": 1495,
  "discountPercent": 15,
  "vatRate": 25,
  "totalSek": 30498
}

Fälten i svaret (OrderRow) är samma som i Lägg till en orderrad.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Ta bort en orderrad

Nyckel: Läsa och skriva

DELETE/api/v1/orders/{id}/rows/{rowId}

Tar bort raden från ordern och räknar om summorna. Går bara så länge ordern har status order (annars 409).

Parametrar

Parametrar: Ta bort en orderrad
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsOrderns id.
rowIdAdressenstring (uuid)JaKrävsRadens id.

Exempel på anrop

curl -X DELETE "/api/v1/orders/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a/rows/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

204Inget innehållDet gick bra. Svaret har inget innehåll.

Svaret har inget innehåll.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Makulera en order

Nyckel: Läsa och skriva

POST/api/v1/orders/{id}/cancel

Makulerar ordern: den får status cancelled och en händelse skrivs i företagets tidslinje. Det går inte att ångra. Via API:t går det för ordrar som har skapats via API:t (utan säljare) och som har status order. En order med säljare makuleras av säljaren eller av den som sköter fakturorna, i appen (403 här), och en order som har skickats till Fortnox går inte att makulera (409). Anropet har inget innehåll.

Parametrar

Parametrar: Makulera en order
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsId (uuid).
Idempotency-KeyHuvudstringNejGör anropet säkert att skicka igen: samma nyckel och samma innehåll inom 24 timmar ger samma svar utan att något skapas två gånger. Till exempel ett uuid.
  • 1 till 200 tecken.

Exempel på anrop

curl -X POST "/api/v1/orders/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a/cancel" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

200OKDet gick bra.

Exempel på svar

{
  "id": "c7d8e9f0-1a2b-4c3d-9e4f-5a6b7c8d9e0f",
  "orderNumber": 1042,
  "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
  "status": "cancelled",
  "editable": false,
  "orderDate": "2026-10-05",
  "ownerUserId": null,
  "ourReference": null,
  "customerReferenceContactId": "7c1d2e3f-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
  "customerReferenceText": "Inköpsorder 4471",
  "invoiceName": "Nordbygg Entreprenad AB",
  "invoiceStreet": "Box 1234",
  "invoicePostalCode": "751 42",
  "invoiceCity": "Uppsala",
  "invoiceEmail": "faktura@nordbygg.example",
  "paymentTermsDays": 30,
  "vatType": "SEVAT",
  "remark": "Avser serviceavtal 2027.",
  "subtotalSek": 16146,
  "vatSek": 4036.5,
  "roundingSek": 0.5,
  "totalSek": 20183,
  "rows": [
    {
      "id": "b3a2c1d0-9e8f-4a7b-8c6d-5e4f3a2b1c0d",
      "orderId": "c7d8e9f0-1a2b-4c3d-9e4f-5a6b7c8d9e0f",
      "productId": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
      "articleNumber": "1040",
      "description": "Serviceavtal Bas, per månad. Support vardagar 8–17.",
      "quantity": 12,
      "unit": "mån",
      "priceSek": 1495,
      "discountPercent": 10,
      "vatRate": 25,
      "totalSek": 16146
    }
  ],
  "readyAt": null,
  "sentAt": null,
  "invoicedAt": null,
  "paidAt": null,
  "fortnoxInvoiceNumber": null,
  "fortnoxTotalToPaySek": null,
  "fortnoxSyncedAt": null,
  "paymentStatus": null,
  "paymentDueDate": null,
  "paymentBalanceSek": null,
  "paymentOverdueDays": null,
  "createdBy": null,
  "createdAt": "2026-10-05T12:00:00.000Z",
  "updatedAt": "2026-10-06T08:30:00.000Z"
}

Fälten i svaret (Order) är samma som i Lista ordrar.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Artiklar

Artiklarna som används på orderrader.

Lista artiklar

Nyckel: Läsa

GET/api/v1/products

Artiklarna i organisationen, både aktiva och inaktiva, nyast först. Med isActive=true: bara de som går att välja på nya orderrader. Med articleNumber: artikeln med just det numret.

Parametrar

Parametrar: Lista artiklar
NamnPlatsTypKrävsBeskrivning
limitFrågeparameterintegerNejAntal rader per sida, 1 till 200. Standard 50.
  • 1 till 200.
  • Standard:50
cursorFrågeparameterstringNejVärdet i nextCursor från förra svaret, för att hämta nästa sida. Utelämnas för första sidan.
  • 1 till 400 tecken.
sortFrågeparameterstringNejSortering: createdAt eller updatedAt. Standard createdAt.
  • Värden:createdAtupdatedAt
  • Standard:createdAt
orderFrågeparameterstringNejOrdning: desc (nyast först, standard) eller asc (äldst först).
  • Värden:ascdesc
  • Standard:desc
updatedSinceFrågeparameterstring (tidpunkt)NejBara det som ändrats efter den här tidpunkten: rader med updatedAt senare än den, räknat i millisekunder (raden med exakt samma updatedAt som ni skickar kommer inte med igen). För stegvis synk: sort=updatedAt&order=asc&updatedSince=<senaste updatedAt ni fått>.
isActiveFrågeparameterstringNejtrue = bara aktiva artiklar. false = bara inaktiva. Utelämnat: alla.
  • Värden:truefalse
articleNumberFrågeparameterstringNejBara artikeln med exakt det här artikelnumret.
  • 1 till 50 tecken.

Exempel på anrop

curl "/api/v1/products" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

200OKDet gick bra.

Exempel på svar

{
  "data": [
    {
      "id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
      "articleNumber": "1040",
      "name": "Serviceavtal Bas",
      "description": "Serviceavtal Bas, per månad. Support vardagar 8–17.",
      "unit": "mån",
      "priceSek": 1495,
      "vatRate": 25,
      "isActive": true,
      "createdBy": null,
      "createdAt": "2026-10-05T12:00:00.000Z",
      "updatedAt": "2026-10-05T12:00:00.000Z"
    }
  ],
  "nextCursor": null
}
Fälten i svaret (13): Product
Fält i svaret: Lista artiklar
FältTypBeskrivning
dataProduct[]Raderna på den här sidan.
data: idBara läsastring (uuid)Id (uuid).
data: articleNumberstring eller nullArtikelnummer. Finns bara en gång i organisationen. null om artikeln saknar nummer.
data: namestringArtikelns namn.
data: descriptionstring eller nullBeskrivning. Den föreslås som text på orderraden när artikeln väljs. null om den saknas.
data: unitstringEnhet, till exempel st, tim eller mån.
data: priceSeknumberPris per enhet i kronor, exklusive moms.
data: vatRatenumberMomssats i procent, till exempel 25.
data: isActivebooleantrue = artikeln går att välja på nya orderrader. false = inaktiv: den står kvar på gamla ordrar men går inte att välja.
data: createdByBara läsastring eller nullAnvändaren som lade upp artikeln. null när den skapades via API:t eller hämtades från Fortnox.
data: createdAtBara läsastring (tidpunkt)När artikeln lades upp.
data: updatedAtBara läsastring (tidpunkt)När artikeln senast ändrades.
nextCursorstring eller nullSkicka som cursor för att hämta nästa sida. null när det inte finns fler rader.

Bara läsa: fältet finns i svaren men går inte att skicka in.

Fel som kan komma400401403429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Skapa en artikel

Nyckel: Läsa och skriva

POST/api/v1/products

Lägger upp en artikel i artikelregistret, precis som Ny artikel i appen. Artikeln är aktiv från början. Finns artikelnumret redan på en annan artikel svarar API:t 409, med den artikelns id i existingId. Artikeln skickas till Fortnox första gången den används på en faktura.

Parametrar

Parametrar: Skapa en artikel
NamnPlatsTypKrävsBeskrivning
Idempotency-KeyHuvudstringNejGör anropet säkert att skicka igen: samma nyckel och samma innehåll inom 24 timmar ger samma svar utan att något skapas två gånger. Till exempel ett uuid.
  • 1 till 200 tecken.

Innehåll

Skickas som JSON i anropet. Okända fält nekas.

Fält att skicka: Skapa en artikel
FältTypKrävsBeskrivning
articleNumberstring eller nullNejArtikelnummer, högst 50 tecken. Får bara finnas på en artikel i organisationen. null = inget nummer.
  • Högst 50 tecken.
namestringJaKrävsArtikelns namn, högst 200 tecken.
  • 1 till 200 tecken.
descriptionstring eller nullNejBeskrivning, högst 2000 tecken. Föreslås som text på orderraden. null = ingen beskrivning.
  • Högst 2 000 tecken.
unitstring eller nullNejEnhet, högst 20 tecken, till exempel st eller tim. null eller utelämnat i POST ger st.
  • Högst 20 tecken.
priceSeknumberJaKrävsPris per enhet i kronor, exklusive moms. Från 0, högst två decimaler.
  • Minst 0. Högst två decimaler.
vatRatenumberNejMomssats i procent, 0 till 100. Utelämnat i POST ger 25.
  • 0 till 100. Högst två decimaler.

Exempel på anrop

curl -X POST "/api/v1/products" \
  -H "Authorization: Bearer $CRMDATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "articleNumber": "1040",
  "name": "Serviceavtal Bas",
  "description": "Serviceavtal Bas, per månad. Support vardagar 8–17.",
  "unit": "mån",
  "priceSek": 1495,
  "vatRate": 25
}'

Svar

201SkapatSkapat. Location har adressen till det som skapades.

Exempel på svar

{
  "id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
  "articleNumber": "1040",
  "name": "Serviceavtal Bas",
  "description": "Serviceavtal Bas, per månad. Support vardagar 8–17.",
  "unit": "mån",
  "priceSek": 1495,
  "vatRate": 25,
  "isActive": true,
  "createdBy": null,
  "createdAt": "2026-10-05T12:00:00.000Z",
  "updatedAt": "2026-10-05T12:00:00.000Z"
}

Fälten i svaret (Product) är samma som i Lista artiklar.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Hämta en artikel

Nyckel: Läsa

GET/api/v1/products/{id}

En artikel, aktiv eller inaktiv.

Parametrar

Parametrar: Hämta en artikel
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsId (uuid).

Exempel på anrop

curl "/api/v1/products/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

200OKDet gick bra.

Exempel på svar

{
  "id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
  "articleNumber": "1040",
  "name": "Serviceavtal Bas",
  "description": "Serviceavtal Bas, per månad. Support vardagar 8–17.",
  "unit": "mån",
  "priceSek": 1495,
  "vatRate": 25,
  "isActive": true,
  "createdBy": null,
  "createdAt": "2026-10-05T12:00:00.000Z",
  "updatedAt": "2026-10-05T12:00:00.000Z"
}

Fälten i svaret (Product) är samma som i Lista artiklar.

Fel som kan komma400401403404429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Ändra en artikel

Nyckel: Läsa och skriva

PATCH/api/v1/products/{id}

Ändrar en artikel. Fält som inte skickas lämnas orörda. null tömmer artikelnummer och beskrivning; null som enhet ger st. Med isActive görs artikeln inaktiv eller aktiv igen. Ordrar som redan har artikeln på en rad ändras inte: raden behåller sin text och sitt pris.

Parametrar

Parametrar: Ändra en artikel
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsId (uuid).

Innehåll

Skickas som JSON i anropet. Okända fält nekas.

Fält att skicka: Ändra en artikel
FältTypKrävsBeskrivning
articleNumberstring eller nullNejArtikelnummer, högst 50 tecken. Får bara finnas på en artikel i organisationen. null = inget nummer.
  • Högst 50 tecken.
namestringNejArtikelns namn, högst 200 tecken.
  • 1 till 200 tecken.
descriptionstring eller nullNejBeskrivning, högst 2000 tecken. Föreslås som text på orderraden. null = ingen beskrivning.
  • Högst 2 000 tecken.
unitstring eller nullNejEnhet, högst 20 tecken, till exempel st eller tim. null eller utelämnat i POST ger st.
  • Högst 20 tecken.
priceSeknumberNejPris per enhet i kronor, exklusive moms. Från 0, högst två decimaler.
  • Minst 0. Högst två decimaler.
vatRatenumberNejMomssats i procent, 0 till 100. Utelämnat i POST ger 25.
  • 0 till 100. Högst två decimaler.
isActivebooleanNejfalse gör artikeln inaktiv: den går inte längre att välja på nya orderrader. true gör den aktiv igen.

Exempel på anrop

curl -X PATCH "/api/v1/products/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a" \
  -H "Authorization: Bearer $CRMDATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "priceSek": 1595,
  "isActive": true
}'

Svar

200OKDet gick bra.

Exempel på svar

{
  "id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a",
  "articleNumber": "1040",
  "name": "Serviceavtal Bas",
  "description": "Serviceavtal Bas, per månad. Support vardagar 8–17.",
  "unit": "mån",
  "priceSek": 1595,
  "vatRate": 25,
  "isActive": true,
  "createdBy": null,
  "createdAt": "2026-10-05T12:00:00.000Z",
  "updatedAt": "2026-10-06T08:30:00.000Z"
}

Fälten i svaret (Product) är samma som i Lista artiklar.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Ringlistor

Ringlistor med företagen som ska ringas.

Lista ringlistor

Nyckel: Läsa

GET/api/v1/call-lists

Organisationens ringlistor med antal rader per status, nyast först. Arkiverade listor visas bara med archived=true. Raderna i en lista hämtas med GET /call-lists/{id}.

Parametrar

Parametrar: Lista ringlistor
NamnPlatsTypKrävsBeskrivning
limitFrågeparameterintegerNejAntal rader per sida, 1 till 200. Standard 50.
  • 1 till 200.
  • Standard:50
cursorFrågeparameterstringNejVärdet i nextCursor från förra svaret, för att hämta nästa sida. Utelämnas för första sidan.
  • 1 till 400 tecken.
sortFrågeparameterstringNejSortering: createdAt eller updatedAt. Standard createdAt.
  • Värden:createdAtupdatedAt
  • Standard:createdAt
orderFrågeparameterstringNejOrdning: desc (nyast först, standard) eller asc (äldst först).
  • Värden:ascdesc
  • Standard:desc
updatedSinceFrågeparameterstring (tidpunkt)NejBara det som ändrats efter den här tidpunkten: rader med updatedAt senare än den, räknat i millisekunder (raden med exakt samma updatedAt som ni skickar kommer inte med igen). För stegvis synk: sort=updatedAt&order=asc&updatedSince=<senaste updatedAt ni fått>.
ownerUserIdFrågeparameterstringNejBara listor med den här ägaren. Id hämtas med GET /users.
  • 1 till 64 tecken.
archivedFrågeparameterstringNejtrue = bara arkiverade listor. false eller utelämnat = bara aktiva listor.
  • Värden:truefalse

Exempel på anrop

curl "/api/v1/call-lists" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

200OKDet gick bra.

Exempel på svar

{
  "data": [
    {
      "id": "a9b8c7d6-e5f4-4a3b-9c2d-1e0f9a8b7c6d",
      "name": "VVS Uppsala oktober",
      "ownerUserId": "Kq3ZxT8mW2pLr9VbN4sYc7JdH1fG6aEu",
      "archivedAt": null,
      "itemCounts": {
        "total": 3,
        "notCalled": 2,
        "answered": 0,
        "noAnswer": 1,
        "notInterested": 0
      },
      "createdBy": null,
      "createdAt": "2026-10-01T08:00:00.000Z",
      "updatedAt": "2026-10-01T08:00:00.000Z"
    }
  ],
  "nextCursor": null
}
Fälten i svaret (15): CallList
Fält i svaret: Lista ringlistor
FältTypBeskrivning
dataCallList[]Raderna på den här sidan.
data: idBara läsastring (uuid)Id (uuid).
data: nameSätts när det skapasstringRinglistans namn.
data: ownerUserIdSätts när det skapasstring eller nullListans ägare: säljaren som ringer. null för en lista utan ägare; den syns i appen bara för dem som får skapa ringlistor åt andra.
data: archivedAtBara läsastring (tidpunkt) eller nullNär listan arkiverades. null för en aktiv lista.
data: itemCountsBara läsaobjectAntal rader i listan, totalt och per status.
data.itemCounts: totalintegerAlla rader i listan.
data.itemCounts: notCalledintegerRader med status not_called: kvar att ringa.
data.itemCounts: answeredintegerRader med status answered.
data.itemCounts: noAnswerintegerRader med status no_answer.
data.itemCounts: notInterestedintegerRader med status not_interested.
data: createdByBara läsastring eller nullAnvändaren som skapade listan. null när den skapades via API:t.
data: createdAtBara läsastring (tidpunkt)När listan skapades.
data: updatedAtBara läsastring (tidpunkt)När listan senast ändrades (skapades eller arkiverades). Ändras inte när rader läggs till eller får ny status.
nextCursorstring eller nullSkicka som cursor för att hämta nästa sida. null när det inte finns fler rader.

Bara läsa: fältet finns i svaren men går inte att skicka in.

Sätts när det skapas: fältet anges när objektet skapas (POST) och går sedan inte att ändra.

Fel som kan komma400401403429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Skapa en ringlista

Nyckel: Läsa och skriva

POST/api/v1/call-lists

Skapar en tom ringlista, som Ny ringlista i appen. Ange ownerUserId för att ge listan till en säljare: då ser säljaren den under Ringlistor. Utan ägare syns listan i appen bara för dem som får skapa ringlistor åt andra. Företag läggs till med POST /call-lists/{id}/items.

Parametrar

Parametrar: Skapa en ringlista
NamnPlatsTypKrävsBeskrivning
Idempotency-KeyHuvudstringNejGör anropet säkert att skicka igen: samma nyckel och samma innehåll inom 24 timmar ger samma svar utan att något skapas två gånger. Till exempel ett uuid.
  • 1 till 200 tecken.

Innehåll

Skickas som JSON i anropet. Okända fält nekas.

Fält att skicka: Skapa en ringlista
FältTypKrävsBeskrivning
namestringJaKrävsListans namn, högst 200 tecken, till exempel VVS Uppsala oktober.
  • 1 till 200 tecken.
ownerUserIdstring eller nullNejSäljaren som ska äga listan. Ska vara en användare i organisationen (GET /users). Utelämnat eller null: ingen ägare.
  • 1 till 64 tecken.

Exempel på anrop

curl -X POST "/api/v1/call-lists" \
  -H "Authorization: Bearer $CRMDATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "VVS Uppsala oktober",
  "ownerUserId": "Kq3ZxT8mW2pLr9VbN4sYc7JdH1fG6aEu"
}'

Svar

201SkapatSkapat. Location har adressen till det som skapades.

Exempel på svar

{
  "id": "a9b8c7d6-e5f4-4a3b-9c2d-1e0f9a8b7c6d",
  "name": "VVS Uppsala oktober",
  "ownerUserId": "Kq3ZxT8mW2pLr9VbN4sYc7JdH1fG6aEu",
  "archivedAt": null,
  "itemCounts": {
    "total": 0,
    "notCalled": 0,
    "answered": 0,
    "noAnswer": 0,
    "notInterested": 0
  },
  "createdBy": null,
  "createdAt": "2026-10-01T08:00:00.000Z",
  "updatedAt": "2026-10-01T08:00:00.000Z"
}

Fälten i svaret (CallList) är samma som i Lista ringlistor.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Hämta en ringlista med rader

Nyckel: Läsa

GET/api/v1/call-lists/{id}

En ringlista med antal rader per status och sina rader: vilka företag som står i listan, status, antal försök och anteckning för vart och ett. Raderna kommer sidvis som i andra listor (limit, cursor, sort, order, updatedSince), med 200 rader per sida om inget annat anges: en lista med högst så många rader kommer i ett svar, en större hämtas med nextCursor tills det är null. itemCounts gäller alltid hela listan. För att följa hur det går i en lista: sort=updatedAt&order=asc&updatedSince=<tidpunkt>. Fungerar också för en arkiverad lista.

Parametrar

Parametrar: Hämta en ringlista med rader
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsId (uuid).
limitFrågeparameterintegerNejAntal rader per sida, 1 till 200. Standard 200: en lista med högst så många rader kommer i ett svar.
  • 1 till 200.
  • Standard:200
cursorFrågeparameterstringNejVärdet i nextCursor från förra svaret, för att hämta nästa sida. Utelämnas för första sidan.
  • 1 till 400 tecken.
sortFrågeparameterstringNejSortering: createdAt eller updatedAt. Standard createdAt.
  • Värden:createdAtupdatedAt
  • Standard:createdAt
orderFrågeparameterstringNejOrdning: asc (listans ordning, standard) eller desc (nyast först).
  • Värden:ascdesc
  • Standard:asc
updatedSinceFrågeparameterstring (tidpunkt)NejBara det som ändrats efter den här tidpunkten: rader med updatedAt senare än den, räknat i millisekunder (raden med exakt samma updatedAt som ni skickar kommer inte med igen). För stegvis synk: sort=updatedAt&order=asc&updatedSince=<senaste updatedAt ni fått>.

Exempel på anrop

curl "/api/v1/call-lists/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

200OKDet gick bra.

Exempel på svar

{
  "id": "a9b8c7d6-e5f4-4a3b-9c2d-1e0f9a8b7c6d",
  "name": "VVS Uppsala oktober",
  "ownerUserId": "Kq3ZxT8mW2pLr9VbN4sYc7JdH1fG6aEu",
  "archivedAt": null,
  "itemCounts": {
    "total": 3,
    "notCalled": 2,
    "answered": 0,
    "noAnswer": 1,
    "notInterested": 0
  },
  "createdBy": null,
  "createdAt": "2026-10-01T08:00:00.000Z",
  "updatedAt": "2026-10-01T08:00:00.000Z",
  "items": [
    {
      "id": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
      "callListId": "a9b8c7d6-e5f4-4a3b-9c2d-1e0f9a8b7c6d",
      "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
      "status": "no_answer",
      "attempts": 1,
      "lastCalledAt": "2026-10-05T12:00:00.000Z",
      "note": "Växeln svarade, Anna är tillbaka på torsdag.",
      "createdAt": "2026-10-01T08:00:00.000Z",
      "updatedAt": "2026-10-05T12:00:00.000Z"
    }
  ],
  "nextCursor": null
}
Fälten i svaret (24): CallListWithItems
Fält i svaret: Hämta en ringlista med rader
FältTypBeskrivning
idstring (uuid)Id (uuid).
namestringRinglistans namn.
ownerUserIdstring eller nullListans ägare: säljaren som ringer. null för en lista utan ägare; den syns i appen bara för dem som får skapa ringlistor åt andra.
archivedAtstring (tidpunkt) eller nullNär listan arkiverades. null för en aktiv lista.
itemCountsobjectAntal rader i listan, totalt och per status.
itemCounts: totalintegerAlla rader i listan.
itemCounts: notCalledintegerRader med status not_called: kvar att ringa.
itemCounts: answeredintegerRader med status answered.
itemCounts: noAnswerintegerRader med status no_answer.
itemCounts: notInterestedintegerRader med status not_interested.
createdBystring eller nullAnvändaren som skapade listan. null när den skapades via API:t.
createdAtstring (tidpunkt)När listan skapades.
updatedAtstring (tidpunkt)När listan senast ändrades (skapades eller arkiverades). Ändras inte när rader läggs till eller får ny status.
itemsCallListItem[]Raderna på den här sidan. Med sort=createdAt och order=asc (standard) i listans ordning: den ordning de lades till, också inom ett anrop.
items: idBara läsastring (uuid)Id (uuid).
items: callListIdBara läsastring (uuid)Ringlistan som raden hör till.
items: companyIdBara läsastring (uuid)Företaget som ska ringas.
items: statusstringHur det har gått: not_called (Ej ringt), answered (Svar), no_answer (Ej svar) eller not_interested (Ej intresserad).
  • Värden:not_calledansweredno_answernot_interested
items: attemptsBara läsaintegerAntal samtalsförsök som har registrerats på raden.
items: lastCalledAtBara läsastring (tidpunkt) eller nullNär det senaste försöket registrerades. null om företaget inte är ringt.
items: notestring eller nullDen senaste anteckningen som skrevs när en status sattes. null om ingen har skrivits.
items: createdAtBara läsastring (tidpunkt)När företaget lades i listan.
items: updatedAtBara läsastring (tidpunkt)När raden senast ändrades.
nextCursorstring eller nullSkicka som cursor för att hämta nästa sida med rader. null när alla rader är med.

Bara läsa: fältet finns i svaren men går inte att skicka in.

Fel som kan komma400401403404429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Arkivera en ringlista

Nyckel: Läsa och skriva

PATCH/api/v1/call-lists/{id}

Arkiverar listan, som Arkivera lista i appen: den försvinner från Ringlistor i appen och går sedan inte att ändra. Det går inte att ångra, varken här eller i appen. Raderna finns kvar och går att läsa. Uppgifter och händelser som listan har gett upphov till påverkas inte.

Parametrar

Parametrar: Arkivera en ringlista
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsId (uuid).

Innehåll

Skickas som JSON i anropet. Okända fält nekas.

Fält att skicka: Arkivera en ringlista
FältTypKrävsBeskrivning
archivedbooleanJaKrävstrue arkiverar listan. Inget annat värde går att skicka: en arkiverad lista går inte att ta fram igen.
  • Alltid:true

Exempel på anrop

curl -X PATCH "/api/v1/call-lists/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a" \
  -H "Authorization: Bearer $CRMDATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "archived": true
}'

Svar

200OKDet gick bra.

Exempel på svar

{
  "id": "a9b8c7d6-e5f4-4a3b-9c2d-1e0f9a8b7c6d",
  "name": "VVS Uppsala oktober",
  "ownerUserId": "Kq3ZxT8mW2pLr9VbN4sYc7JdH1fG6aEu",
  "archivedAt": "2026-10-06T08:30:00.000Z",
  "itemCounts": {
    "total": 3,
    "notCalled": 2,
    "answered": 0,
    "noAnswer": 1,
    "notInterested": 0
  },
  "createdBy": null,
  "createdAt": "2026-10-01T08:00:00.000Z",
  "updatedAt": "2026-10-06T08:30:00.000Z"
}

Fälten i svaret (CallList) är samma som i Lista ringlistor.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Lägg till företag i en ringlista

Nyckel: Läsa och skriva

POST/api/v1/call-lists/{id}/items

Lägger sparade företag sist i listan, i den ordning de anges. Företag som inte går att lägga till hoppas över och räknas upp i skipped med skälet: not_found (finns inte bland era sparade företag), do_not_contact (märkt Kontakta inte) eller already_in_list (står redan i listan). Anropet lyckas även om alla hoppas över.

Parametrar

Parametrar: Lägg till företag i en ringlista
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsRinglistans id.
Idempotency-KeyHuvudstringNejGör anropet säkert att skicka igen: samma nyckel och samma innehåll inom 24 timmar ger samma svar utan att något skapas två gånger. Till exempel ett uuid.
  • 1 till 200 tecken.

Innehåll

Skickas som JSON i anropet. Okända fält nekas.

Fält att skicka: Lägg till företag i en ringlista
FältTypKrävsBeskrivning
companyIds(string (uuid))[]JaKrävsId för företagen som ska läggas till, 1 till 200 i ett anrop.
  • 1 till 200 värden.

Exempel på anrop

curl -X POST "/api/v1/call-lists/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a/items" \
  -H "Authorization: Bearer $CRMDATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "companyIds": [
    "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
    "3a4b5c6d-7e8f-4a9b-8c0d-1e2f3a4b5c6d"
  ]
}'

Svar

200OKDet gick bra.

Exempel på svar

{
  "added": [
    {
      "id": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
      "callListId": "a9b8c7d6-e5f4-4a3b-9c2d-1e0f9a8b7c6d",
      "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
      "status": "not_called",
      "attempts": 0,
      "lastCalledAt": null,
      "note": null,
      "createdAt": "2026-10-05T12:00:00.000Z",
      "updatedAt": "2026-10-05T12:00:00.000Z"
    }
  ],
  "skipped": [
    {
      "companyId": "3a4b5c6d-7e8f-4a9b-8c0d-1e2f3a4b5c6d",
      "reason": "do_not_contact"
    }
  ]
}
Fälten i svaret (13)
Fält i svaret: Lägg till företag i en ringlista
FältTypBeskrivning
addedCallListItem[]Raderna som lades till, i listans ordning.
added: idBara läsastring (uuid)Id (uuid).
added: callListIdBara läsastring (uuid)Ringlistan som raden hör till.
added: companyIdBara läsastring (uuid)Företaget som ska ringas.
added: statusstringHur det har gått: not_called (Ej ringt), answered (Svar), no_answer (Ej svar) eller not_interested (Ej intresserad).
  • Värden:not_calledansweredno_answernot_interested
added: attemptsBara läsaintegerAntal samtalsförsök som har registrerats på raden.
added: lastCalledAtBara läsastring (tidpunkt) eller nullNär det senaste försöket registrerades. null om företaget inte är ringt.
added: notestring eller nullDen senaste anteckningen som skrevs när en status sattes. null om ingen har skrivits.
added: createdAtBara läsastring (tidpunkt)När företaget lades i listan.
added: updatedAtBara läsastring (tidpunkt)När raden senast ändrades.
skippedobject[]Företagen som inte lades till, med skälet.
skipped: companyIdstring (uuid)Företaget som hoppades över.
skipped: reasonstringVarför: not_found, do_not_contact eller already_in_list.
  • Värden:not_founddo_not_contactalready_in_list

Bara läsa: fältet finns i svaren men går inte att skicka in.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Sätt status på en rad

Nyckel: Läsa och skriva

PATCH/api/v1/call-lists/{id}/items/{itemId}

Registrerar hur ett samtal gick, som knapparna Svar, Ej svar och Ej intresserad i appen. Varje anrop med en annan status än not_called räknas som ett samtalsförsök och skrivs i företagets tidslinje. answered räknas dessutom som kontakt med företaget (senaste kontakt uppdateras). no_answer skapar uppgiften Ring igen om två dagar, till listans ägare, utom när företaget är märkt Kontakta inte. not_called återställer raden utan att något annat händer; antalet försök står kvar.

Parametrar

Parametrar: Sätt status på en rad
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsRinglistans id.
itemIdAdressenstring (uuid)JaKrävsRadens id.

Innehåll

Skickas som JSON i anropet. Okända fält nekas.

Fält att skicka: Sätt status på en rad
FältTypKrävsBeskrivning
statusstringJaKrävsDen nya statusen: not_called, answered, no_answer eller not_interested.
  • Värden:not_calledansweredno_answernot_interested
notestringNejAnteckning om samtalet (valfri), högst 500 tecken. Den sparas på raden och skrivs i tidslinjen. Utelämnad eller tom: radens anteckning lämnas orörd.
  • Högst 500 tecken.

Exempel på anrop

curl -X PATCH "/api/v1/call-lists/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a/items/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a" \
  -H "Authorization: Bearer $CRMDATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "status": "no_answer",
  "note": "Växeln svarade, Anna är tillbaka på torsdag."
}'

Svar

200OKDet gick bra.

Exempel på svar

{
  "id": "e1f2a3b4-c5d6-4e7f-8a9b-0c1d2e3f4a5b",
  "callListId": "a9b8c7d6-e5f4-4a3b-9c2d-1e0f9a8b7c6d",
  "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
  "status": "no_answer",
  "attempts": 1,
  "lastCalledAt": "2026-10-05T12:00:00.000Z",
  "note": "Växeln svarade, Anna är tillbaka på torsdag.",
  "createdAt": "2026-10-01T08:00:00.000Z",
  "updatedAt": "2026-10-05T12:00:00.000Z"
}
Fälten i svaret (9): CallListItem
Fält i svaret: Sätt status på en rad
FältTypBeskrivning
idBara läsastring (uuid)Id (uuid).
callListIdBara läsastring (uuid)Ringlistan som raden hör till.
companyIdBara läsastring (uuid)Företaget som ska ringas.
statusstringHur det har gått: not_called (Ej ringt), answered (Svar), no_answer (Ej svar) eller not_interested (Ej intresserad).
  • Värden:not_calledansweredno_answernot_interested
attemptsBara läsaintegerAntal samtalsförsök som har registrerats på raden.
lastCalledAtBara läsastring (tidpunkt) eller nullNär det senaste försöket registrerades. null om företaget inte är ringt.
notestring eller nullDen senaste anteckningen som skrevs när en status sattes. null om ingen har skrivits.
createdAtBara läsastring (tidpunkt)När företaget lades i listan.
updatedAtBara läsastring (tidpunkt)När raden senast ändrades.

Bara läsa: fältet finns i svaren men går inte att skicka in.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Ta bort en rad ur en ringlista

Nyckel: Läsa och skriva

DELETE/api/v1/call-lists/{id}/items/{itemId}

Tar bort företaget ur listan. Företaget självt, dess tidslinje och uppgifter som listan har skapat påverkas inte.

Parametrar

Parametrar: Ta bort en rad ur en ringlista
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsRinglistans id.
itemIdAdressenstring (uuid)JaKrävsRadens id.

Exempel på anrop

curl -X DELETE "/api/v1/call-lists/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a/items/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

204Inget innehållDet gick bra. Svaret har inget innehåll.

Svaret har inget innehåll.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Taggar

Taggarna som finns i organisationen. Taggar sätts på företag.

Lista taggar

Nyckel: Läsa

GET/api/v1/tags

Alla taggar i organisationen, i bokstavsordning. Listan kommer alltid på en sida. Taggar sätts på ett företag med PATCH /companies/{id}, och företag med en viss tagg hämtas med GET /companies?tag=<namn>.

Exempel på anrop

curl "/api/v1/tags" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

200OKDet gick bra.

Exempel på svar

{
  "data": [
    {
      "id": "7c1e2b9a-4d3f-4a6b-8c5d-9e0f1a2b3c4d",
      "name": "Mässa 2026",
      "createdAt": "2026-04-21T07:45:00.000Z"
    },
    {
      "id": "0a9b8c7d-6e5f-4a3b-9c2d-1e0f9a8b7c6d",
      "name": "VIP",
      "createdAt": "2026-03-14T09:30:00.000Z"
    }
  ],
  "nextCursor": null
}
Fälten i svaret (5): Tag
Fält i svaret: Lista taggar
FältTypBeskrivning
dataTag[]Raderna på den här sidan.
data: idstring (uuid)Taggens id (uuid).
data: namestringTaggens namn, så som det visas i appen. Det är namnet som används i tags på ett företag och i filtret tag.
data: createdAtstring (tidpunkt)När taggen skapades.
nextCursorstring eller nullSkicka som cursor för att hämta nästa sida. null när det inte finns fler rader.
Fel som kan komma400401403429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Användare

Användarna i organisationen, för att kunna ange ansvarig.

Lista användare

Nyckel: Läsa

GET/api/v1/users

Användarna i organisationen, i bokstavsordning, med id, namn, e-postadress och roll. Listan kommer alltid på en sida. Användarens id är det som anges som ansvarig på företag, affärer, uppgifter och ringlistor.

Exempel på anrop

curl "/api/v1/users" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

200OKDet gick bra.

Exempel på svar

{
  "data": [
    {
      "id": "pQ7mX2kV9sLwT4bN8cRd3fGh",
      "name": "Anna Lindqvist",
      "email": "anna.lindqvist@exempelbolaget.example",
      "role": {
        "key": "admin",
        "name": "Admin"
      }
    },
    {
      "id": "Zt5hK8nW3yBq6vJm1xCe9aLp",
      "name": "Erik Sandberg",
      "email": "erik.sandberg@exempelbolaget.example",
      "role": {
        "key": "sales",
        "name": "Säljare"
      }
    }
  ],
  "nextCursor": null
}
Fälten i svaret (8): User
Fält i svaret: Lista användare
FältTypBeskrivning
dataUser[]Raderna på den här sidan.
data: idstringAnvändarens id. Det är det här värdet som anges som ansvarig, till exempel i ownerUserId.
data: namestringAnvändarens namn.
data: emailstringAnvändarens e-postadress (den hen loggar in med).
data: roleobject eller nullAnvändarens roll i organisationen. null om användaren inte har fått någon roll än.
data.role: keystringRollens nyckel: admin, finance eller sales för de fasta rollerna, custom-… för era egna.
data.role: namestringRollens namn, så som det visas i appen.
nextCursorstring eller nullSkicka som cursor för att hämta nästa sida. null när det inte finns fler rader.
Fel som kan komma400401403429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Webhooks

Låt CRMdata meddela era system när något händer.

Lista webhooks

Nyckel: Läsa och skriva

GET/api/v1/webhooks

Organisationens webhooks, nyast först. Alla ryms på en sida (högst 50 per organisation, avstängda inräknade). Hemligheten visas aldrig här. Kräver en nyckel som får skriva, eftersom adresserna kan fungera som lösenord hos mottagaren.

Exempel på anrop

curl "/api/v1/webhooks" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

200OKDet gick bra.

Exempel på svar

{
  "data": [
    {
      "id": "4e1f6a2b-9c3d-4e5f-8a7b-6c5d4e3f2a1b",
      "name": "Affärssystemet",
      "url": "https://affarssystemet.exempelbolaget.se/crmdata/webhook",
      "events": [
        "deal.won",
        "order.created"
      ],
      "status": "active",
      "pausedReason": null,
      "consecutiveFailures": 0,
      "lastSuccessAt": "2026-10-06T09:15:00.000Z",
      "lastFailureAt": null,
      "createdAt": "2026-10-05T12:00:00.000Z"
    }
  ],
  "nextCursor": null
}
Fälten i svaret (12): Webhook
Fält i svaret: Lista webhooks
FältTypBeskrivning
dataWebhook[]Webhookarna.
data: idBara läsastring (uuid)Webhookens id.
data: namestringErt namn på kopplingen, till exempel Affärssystemet.
data: urlstringAdressen meddelandena skickas till (https).
data: eventsstring[]Händelsetyperna som skickas, till exempel deal.won. Tom lista = alla händelser.
data: statusstringactive = skickar. paused = stoppad av CRMdata efter för många misslyckade leveranser i rad (se pausedReason); det som händer under pausen väntar och skickas när ni startar den igen med PATCH status active. disabled = avstängd av er, eller av CRMdata när adressen svarade 410 Gone (se pausedReason); det som händer under tiden skickas aldrig.
  • Värden:activepauseddisabled
data: pausedReasonBara läsastring eller nullVarför CRMdata pausade webhooken, eller stängde av den när adressen svarade 410 Gone. null när den är igång eller när ni själva stängde av den.
data: consecutiveFailuresBara läsaintegerLeveranser i rad där alla försök gått åt. Vid 20 pausas webhooken. Nollas vid en lyckad leverans.
data: lastSuccessAtBara läsastring (tidpunkt) eller nullNär en leverans senast lyckades. null om ingen har lyckats än.
data: lastFailureAtBara läsastring (tidpunkt) eller nullNär ett försök senast misslyckades. null om inget har misslyckats.
data: createdAtBara läsastring (tidpunkt)När webhooken skapades.
nextCursornullAlltid null: alla ryms på en sida.

Bara läsa: fältet finns i svaren men går inte att skicka in.

Fel som kan komma400401403429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Skapa en webhook

Nyckel: Läsa och skriva

POST/api/v1/webhooks

Skapar en webhook: CRMdata skickar ett meddelande (POST med JSON) till adressen varje gång en av händelserna inträffar. Svaret innehåller hemligheten för signaturen, en enda gång: spara den på er server. Adressen måste börja med https:// och nås från internet; adresser in i lokala eller privata nät nekas, liksom en adress som innehåller ett personnummer. Högst 10 webhooks per organisation som är igång eller pausade; avstängda räknas inte, men alla tillsammans får vara högst 50. Över taket: 403. Varje meddelande har huvudena CRMdata-Event (händelsetypen), CRMdata-Delivery (leveransens id) och CRMdata-Signature (t=<unix-sekunder>,v1=<hex hmac-sha256(hemlighet, t + "." + innehållet)>). Svara 2xx inom 10 sekunder. Allt annat räknas som misslyckat och vi försöker igen efter 1, 5, 30, 120, 360, 720 minuter. Svarar adressen 410 Gone stängs webhooken av direkt (status disabled), utan nya försök: så avslutar till exempel Zapier en prenumeration. Hur meddelandena ser ut beskrivs under webhooks i OpenAPI-filen. Idempotency-Key gäller inte här. Svaret innehåller hemligheten, och den sparas aldrig hos oss i klartext, inte heller för att kunna skicka samma svar igen. Varje anrop skapar därför en ny webhook. Kom svaret aldrig fram: hämta webhookarna med GET /webhooks, ta bort den som skapades och skapa en ny.

Innehåll

Skickas som JSON i anropet. Okända fält nekas.

Fält att skicka: Skapa en webhook
FältTypKrävsBeskrivning
namestringJaKrävsErt namn på kopplingen, till exempel Affärssystemet. Högst 100 tecken.
  • 1 till 100 tecken.
urlstringJaKrävsAdressen meddelandena ska skickas till. Måste börja med https:// och nås från internet (inte ett lokalt eller privat nät). Får inte innehålla ett personnummer. Sparas i normaliserad form (t.ex. små bokstäver i värdnamnet).
  • 1 till 2 000 tecken.
eventsstring[]NejHändelsetyperna som ska skickas, till exempel ["deal.won", "order.created"]. Tom lista = alla händelser. Typerna finns i GET /webhook-events.
  • Högst 16 värden.

Exempel på anrop

curl -X POST "/api/v1/webhooks" \
  -H "Authorization: Bearer $CRMDATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "name": "Affärssystemet",
  "url": "https://affarssystemet.exempelbolaget.se/crmdata/webhook",
  "events": [
    "deal.won",
    "order.created"
  ]
}'

Svar

201SkapatSkapat. Location har adressen till det som skapades.

Exempel på svar

{
  "id": "4e1f6a2b-9c3d-4e5f-8a7b-6c5d4e3f2a1b",
  "name": "Affärssystemet",
  "url": "https://affarssystemet.exempelbolaget.se/crmdata/webhook",
  "events": [
    "deal.won",
    "order.created"
  ],
  "status": "active",
  "pausedReason": null,
  "consecutiveFailures": 0,
  "lastSuccessAt": null,
  "lastFailureAt": null,
  "createdAt": "2026-10-05T12:00:00.000Z",
  "secret": "whsec_Qm9yYSBpbnRlIHNwYXJhIGhlbWxpZ2hldGVuIGkgZW4gd2ViYnNpZGE"
}
Fälten i svaret (11): WebhookCreated
Fält i svaret: Skapa en webhook
FältTypBeskrivning
idBara läsastring (uuid)Webhookens id.
namestringErt namn på kopplingen, till exempel Affärssystemet.
urlstringAdressen meddelandena skickas till (https).
eventsstring[]Händelsetyperna som skickas, till exempel deal.won. Tom lista = alla händelser.
statusBara läsastringactive = skickar. paused = stoppad av CRMdata efter för många misslyckade leveranser i rad (se pausedReason); det som händer under pausen väntar och skickas när ni startar den igen med PATCH status active. disabled = avstängd av er, eller av CRMdata när adressen svarade 410 Gone (se pausedReason); det som händer under tiden skickas aldrig.
  • Värden:activepauseddisabled
pausedReasonBara läsastring eller nullVarför CRMdata pausade webhooken, eller stängde av den när adressen svarade 410 Gone. null när den är igång eller när ni själva stängde av den.
consecutiveFailuresBara läsaintegerLeveranser i rad där alla försök gått åt. Vid 20 pausas webhooken. Nollas vid en lyckad leverans.
lastSuccessAtBara läsastring (tidpunkt) eller nullNär en leverans senast lyckades. null om ingen har lyckats än.
lastFailureAtBara läsastring (tidpunkt) eller nullNär ett försök senast misslyckades. null om inget har misslyckats.
createdAtBara läsastring (tidpunkt)När webhooken skapades.
secretBara läsastringHemligheten för signaturen (börjar på whsec_). Visas bara här, en gång: spara den på er server. Används för att kontrollera CRMdata-Signature på varje meddelande.

Bara läsa: fältet finns i svaren men går inte att skicka in.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Hämta en webhook

Nyckel: Läsa och skriva

GET/api/v1/webhooks/{id}

En webhook med sitt läge och sina räknare. Hemligheten visas aldrig. Kräver en nyckel som får skriva, eftersom adressen kan fungera som lösenord hos mottagaren.

Parametrar

Parametrar: Hämta en webhook
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsId (uuid).

Exempel på anrop

curl "/api/v1/webhooks/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

200OKDet gick bra.

Exempel på svar

{
  "id": "4e1f6a2b-9c3d-4e5f-8a7b-6c5d4e3f2a1b",
  "name": "Affärssystemet",
  "url": "https://affarssystemet.exempelbolaget.se/crmdata/webhook",
  "events": [
    "deal.won",
    "order.created"
  ],
  "status": "active",
  "pausedReason": null,
  "consecutiveFailures": 0,
  "lastSuccessAt": "2026-10-06T09:15:00.000Z",
  "lastFailureAt": null,
  "createdAt": "2026-10-05T12:00:00.000Z"
}

Fälten i svaret (Webhook) är samma som i Lista webhooks.

Fel som kan komma400401403404429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Ändra en webhook

Nyckel: Läsa och skriva

PATCH/api/v1/webhooks/{id}

Ändrar namn, adress, händelser eller läge. Fält som inte skickas lämnas orörda. status active startar en webhook som är avstängd eller som CRMdata har pausat: räknaren nollas och de leveranser som väntar skickas. En avstängd webhook räknas mot taket igen när den startas: är redan 10 andra igång eller pausade svarar API:t 403. status disabled stänger av den: det som händer medan den är avstängd skickas aldrig. En ny adress kontrolleras på samma sätt som när webhooken skapas. Hemligheten går inte att byta: ta bort webhooken och skapa en ny.

Parametrar

Parametrar: Ändra en webhook
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsId (uuid).

Innehåll

Skickas som JSON i anropet. Okända fält nekas.

Fält att skicka: Ändra en webhook
FältTypKrävsBeskrivning
namestringNejErt namn på kopplingen, till exempel Affärssystemet. Högst 100 tecken.
  • 1 till 100 tecken.
urlstringNejAdressen meddelandena ska skickas till. Måste börja med https:// och nås från internet (inte ett lokalt eller privat nät). Får inte innehålla ett personnummer. Sparas i normaliserad form (t.ex. små bokstäver i värdnamnet).
  • 1 till 2 000 tecken.
eventsstring[]NejHändelsetyperna som ska skickas, till exempel ["deal.won", "order.created"]. Tom lista = alla händelser. Typerna finns i GET /webhook-events.
  • Högst 16 värden.
statusstringNejactive startar webhooken (också en som CRMdata pausat: räknaren nollas och väntande leveranser skickas). disabled stänger av den: det som händer medan den är avstängd skickas aldrig, men leveranser som redan väntar ligger kvar tills den startas igen.
  • Värden:activedisabled

Exempel på anrop

curl -X PATCH "/api/v1/webhooks/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a" \
  -H "Authorization: Bearer $CRMDATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "events": [
    "deal.won",
    "deal.lost",
    "order.created"
  ],
  "status": "active"
}'

Svar

200OKDet gick bra.

Exempel på svar

{
  "id": "4e1f6a2b-9c3d-4e5f-8a7b-6c5d4e3f2a1b",
  "name": "Affärssystemet",
  "url": "https://affarssystemet.exempelbolaget.se/crmdata/webhook",
  "events": [
    "deal.won",
    "deal.lost",
    "order.created"
  ],
  "status": "active",
  "pausedReason": null,
  "consecutiveFailures": 0,
  "lastSuccessAt": "2026-10-06T09:15:00.000Z",
  "lastFailureAt": null,
  "createdAt": "2026-10-05T12:00:00.000Z"
}

Fälten i svaret (Webhook) är samma som i Lista webhooks.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Ta bort en webhook

Nyckel: Läsa och skriva

DELETE/api/v1/webhooks/{id}

Tar bort webhooken och dess logg över leveranser. Inget mer skickas till adressen. Det går inte att ångra.

Parametrar

Parametrar: Ta bort en webhook
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsId (uuid).

Exempel på anrop

curl -X DELETE "/api/v1/webhooks/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

204Inget innehållDet gick bra. Svaret har inget innehåll.

Svaret har inget innehåll.

Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Skicka en testhändelse

Nyckel: Läsa och skriva

POST/api/v1/webhooks/{id}/ping

Lägger en testhändelse av typen ping i kön till webhooken, med ett påhittat objekt i data. Den skickas inom några sekunder, signerad som alla andra meddelanden, så att ni kan prova mottagaren. Webhooken måste vara igång (status active). En testhändelse räknas inte mot gränsen för att pausa webhooken.

Parametrar

Parametrar: Skicka en testhändelse
NamnPlatsTypKrävsBeskrivning
idAdressenstring (uuid)JaKrävsId (uuid).
Idempotency-KeyHuvudstringNejGör anropet säkert att skicka igen: samma nyckel och samma innehåll inom 24 timmar ger samma svar utan att något skapas två gånger. Till exempel ett uuid.
  • 1 till 200 tecken.

Exempel på anrop

curl -X POST "/api/v1/webhooks/2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a/ping" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

200OKDet gick bra.

Exempel på svar

{
  "deliveryId": "0f9e8d7c-6b5a-4493-8271-605f4e3d2c1b",
  "eventId": "5a4b3c2d-1e0f-4a9b-8c7d-6e5f4a3b2c1d"
}
Fälten i svaret (2): WebhookPing
Fält i svaret: Skicka en testhändelse
FältTypBeskrivning
deliveryIdstring (uuid)Leveransens id. Står i huvudet CRMdata-Delivery på meddelandet.
eventIdstring (uuid)Testhändelsens id. Står i meddelandets id.
Fel som kan komma400401403404409413422429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 404Finns inte, eller hör till en annan organisation (samma svar).
  • 409Krockar med något som redan finns eller med läget. conflict: till exempel ett företag som redan är sparat (då med existingId). idempotency_key_reused: samma Idempotency-Key med annat innehåll. request_in_progress: det första anropet med samma Idempotency-Key pågår.
  • 413Innehållet är större än 1 MB.
  • 422Formatet stämmer, men värdet går inte att använda (en regel i CRM:et säger nej).
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Lista händelsetyper

Nyckel: Läsa

GET/api/v1/webhook-events

Händelsetyperna som webhooks kan prenumerera på, med texter på svenska. Namnen är fasta. Meddelandets data är objektet händelsen gäller, i samma form som API:t ger det (ett företag för company.*, en kontakt för contact.* och så vidare); för en borttagen kontakt är det kontakten som den var.

Exempel på anrop

curl "/api/v1/webhook-events" \
  -H "Authorization: Bearer $CRMDATA_API_KEY"

Svar

200OKDet gick bra.

Exempel på svar

{
  "data": [
    {
      "type": "company.created",
      "entity": "company",
      "label": "Företag sparat",
      "description": "Ett nytt företag sparades (från Prospektera, för hand eller via API:t)."
    },
    {
      "type": "company.updated",
      "entity": "company",
      "label": "Företag ändrat",
      "description": "Uppgifterna på ett företag ändrades (alias, ansvarig, adresser, taggar, kontakta inte …), också när nya uppgifter från företagsdatan har förts in."
    }
  ],
  "nextCursor": null
}
Fälten i svaret (6): WebhookEventType
Fält i svaret: Lista händelsetyper
FältTypBeskrivning
dataWebhookEventType[]Händelsetyperna.
data: typestringHändelsetypen, så som den anges i events och skickas i type och huvudet CRMdata-Event.
data: entitystringVilken sorts objekt händelsen gäller. Meddelandets data är det objektet, i samma form som API:t ger det.
  • Värden:companycontactnotetaskdealorder
data: labelstringKort namn på svenska.
data: descriptionstringNär händelsen skickas.
nextCursornullAlltid null: alla ryms på en sida.
Fel som kan komma400401403429500503
  • 400Anropet går inte att läsa eller stämmer inte. invalid_json: innehållet är inte JSON. validation_failed: ett eller flera fält stämmer inte, se details. unknown_field: ett fält som inte finns.
  • 401Ingen eller fel nyckel. missing_key: huvudet Authorization saknas. invalid_key: nyckeln finns inte. revoked_key: nyckeln är indragen.
  • 403Nyckeln får inte göra det här. read_only_key: nyckeln får bara läsa. plan_required: API:t ingår inte i abonnemanget. forbidden: inte tillåtet av en annan regel.
  • 429För många anrop: högst 300 per minut och nyckel. Retry-After säger hur många sekunder ni ska vänta.
  • 500Ett fel hos oss. Svaret har aldrig några detaljer, bara requestId.
  • 503API:t är upptaget: ingen ledig anslutning till databasen i tid, eller en fråga som tog för lång tid. Inte ett fel i anropet. Retry-After säger hur många sekunder ni ska vänta.

Alla fel har samma form. Se Svar och fel.

Webhooks

CRMdata meddelar era system när något händer, i stället för att ni frågar API:t med jämna mellanrum.

Så fungerar det

En webhook är en adress på er server som CRMdata skickar ett meddelande till när något händer i er organisation: ett företag sparas, en affär vinns, en order skapas. Ert system behöver då inte fråga API:t med jämna mellanrum.

  • Snabbt. Meddelandet skickas inom några sekunder, med POST som JSON. Det innehåller objektet i samma form som API:t ger det, så ni behöver sällan göra ett anrop tillbaka.
  • Signerat. Varje meddelande har en signatur räknad med en hemlighet som bara ni och CRMdata känner till. Så vet ert system att meddelandet kommer från CRMdata, se Kontrollera signaturen.
  • Tåligt. Svarar er server inte försöker vi igen i upp till ett dygn, se Omförsök och paus.
  • Samma regler som API:t. Webhooks ingår för organisationer med betalt abonnemang och sköts av en administratör. En organisation kan ha högst 10 webhooks som är igång eller pausade; avstängda räknas inte, men alla tillsammans får vara högst 50. Allt som görs i appen eller via API:t ger meddelanden; det som läggs in med Import från Excel gör det inte.

Skapa en webhook

  1. Gör klart en adress på er server

    Adressen ska ta emot POST med JSON och svara 200 inom 10 sekunder. Den måste börja med https:// och gå att nå från internet, se Kraven på adressen. Gör det tunga arbetet efter att ni svarat, till exempel i en kö.

  2. Skapa webhooken i appen

    Logga in i CRMdata som administratör och gå till Integrationer → Webhooks. Ange ett namn, adressen och vilka händelser som ska skickas (eller alla). Hemligheten visas en enda gång: spara den direkt som en miljövariabel i systemet som tar emot meddelandena. Namn, adress och händelser går att ändra senare med Ändra, och hemligheten är då densamma.

  3. Skicka en testhändelse

    Knappen Skicka testhändelse på webhooken skickar ett meddelande av typen ping med ett påhittat objekt. Under Senaste utskick ser ni vad er server svarade. Där står också varje riktigt utskick sedan, med svar och antal försök.

Webhooks går också att skapa, ändra och ta bort via API:t med en nyckel som får skriva, se resursen Webhooks. Då kan till exempel en integrationsplattform prenumerera själv. Hemligheten kommer i svaret när webhooken skapas, en enda gång.

Meddelandet

Varje händelse skickas som ett eget anrop till adressen. Så här ser huvudena ut:

POST /crmdata HTTP/1.1
Host: er-server.se
Content-Type: application/json
User-Agent: CRMdata-Webhooks/1
CRMdata-Event: deal.won
CRMdata-Delivery: 2b7c9e1f-8a3d-4b6e-a1c5-7d9f0e2b4a68
CRMdata-Signature: t=1791278045,v1=5f1a9c3e7b2d4f6a8c0e1b3d5f7a9c2e4b6d8f0a1c3e5b7d9f2a4c6e8b0d1f3a
Huvuden i meddelandet
HuvudBeskrivning
CRMdata-EventHändelsetypen, samma som type i innehållet. Till exempel deal.won.
CRMdata-DeliveryUtskickets id: ett per webhook och händelse, samma vid ett nytt försök. Händelsens eget id står i innehållet.
CRMdata-SignatureSignaturen: t är tidpunkten som unix-sekunder och v1 är HMAC-SHA256 i hex. Se Kontrollera signaturen.
User-AgentAlltid CRMdata-Webhooks/1.

Innehållet

Innehållet är ett JSON-objekt med fem fält. data är objektet som händelsen gäller, i exakt samma form som API:t ger det (samma fält som i tabellerna vid respektive resurs). För en borttagen kontakt är det kontakten som den var.

Fälten i ett meddelande
FältTypBeskrivning
iduuidHändelsens id. Samma id om samma händelse skulle komma två gånger: spara det och hoppa över det ni redan sett.
typestringHändelsetypen, se Händelser. Testhändelsen har typen ping.
occurredAtdate-timeNär händelsen hände, ISO 8601 i UTC.
organizationIduuidEr organisations id, samma som i GET /me.
dataobjectObjektet som händelsen gäller, i API:ts form. Har objektet hunnit tas bort innan meddelandet skickades innehåller data bara id. För ping ett påhittat objekt.

Exempel: en affär vanns

{
  "id": "6d2f0b7e-4c1a-4e8b-9f3d-2a5c7e9b1d04",
  "type": "deal.won",
  "occurredAt": "2026-10-06T09:14:03.000Z",
  "organizationId": "a3f1c9d2-5e7b-4a8c-b6d0-1f2e3c4b5a69",
  "data": {
    "id": "7c1d2e3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
    "companyId": "2f0c7a8e-3b1d-4c5e-9f6a-7b8c9d0e1f2a",
    "title": "Serviceavtal 2027",
    "valueSek": 185000,
    "pipelineId": "b1c2d3e4-f5a6-4b7c-8d9e-0f1a2b3c4d5e",
    "pipelineName": "Standard",
    "stageId": "a3b4c5d6-e7f8-4a9b-8c0d-1e2f3a4b5c6d",
    "stageName": "Vunnen",
    "status": "won",
    "ownerUserId": "Xk3mPq8RtV2wYz5aBc7dEf9gHj1LnN4s",
    "expectedCloseDate": "2026-11-30",
    "closedAt": "2026-10-06T09:14:03.000Z",
    "closeReason": null,
    "createdBy": null,
    "createdAt": "2026-10-05T08:15:00.000Z",
    "updatedAt": "2026-10-06T09:14:03.000Z"
  }
}
  • Svara 2xx inom 10 sekunder. Allt annat räknas som misslyckat: ett annat svar, inget svar i tid eller ett nätverksfel. Omdirigeringar (3xx) följs inte. Svarar ni 410 Gone stängs webhooken av direkt, utan nya försök: det betyder att adressen inte tar emot meddelanden längre (så avslutar till exempel Zapier en prenumeration).
  • Räkna med dubbletter. Försvinner ert svar på vägen vet vi inte att meddelandet kom fram och skickar det igen. Spara id och gör inget mer när ni ser samma id en gång till.
  • Ett anrop, ett meddelande per objekt. Ändrar ett anrop flera saker på samma objekt, till exempel alias, ansvarig och taggar på ett företag, kommer normalt ett meddelande med objektets senaste läge, inte ett per ändring. Skapas objektet i samma anrop kommer bara .created, med läget efter alla ändringar. Andra händelser om samma objekt, till exempel deal.won, kommer som egna meddelanden.
  • Ordningen. Meddelandena till en webhook skickas i den ordning händelserna skrevs, så en order som skapas kommer före ändringar av den. Ett omförsök kan ändå komma efter senare händelser, och data är objektet som det såg ut när meddelandet togs fram. Behandla därför .created och .updated lika (skapa posten om den saknas, uppdatera den annars), och läs det aktuella läget med API:t om ordningen spelar roll.
  • Personnummer finns aldrig med. Innehållet går genom samma maskering som API:ts svar.

Händelser

Händelserna som går att prenumerera på. Väljer ni Alla händelser får ni också nya typer som läggs till längre fram.

Händelsetyper
TypHändelseNär
Företag
company.createdFöretag sparatEtt nytt företag sparades (från Prospektera, för hand eller via API:t).
company.updatedFöretag ändratUppgifterna på ett företag ändrades (alias, ansvarig, adresser, taggar, kontakta inte …), också när nya uppgifter från företagsdatan har förts in.
Kontakter
contact.createdKontakt skapadEn kontakt lades till på ett företag.
contact.updatedKontakt ändradEn kontakt ändrades, även när den blev huvudkontakt.
contact.deletedKontakt borttagenEn kontakt togs bort. Meddelandet innehåller kontakten som den var.
Anteckningar
note.createdAnteckning skapadEn anteckning skrevs på ett företag.
Uppgifter
task.createdUppgift skapadEn uppgift lades upp.
task.completedUppgift klarEn uppgift klarmarkerades.
Affärer
deal.createdAffär skapadEn affär lades upp i pipelinen.
deal.updatedAffär ändradEn affär flyttades till ett annat steg eller ändrades (rubrik, värde, datum, ansvarig).
deal.wonAffär vunnenEn affär flyttades till, eller skapades i, ett vunnet-steg.
deal.lostAffär förloradEn affär flyttades till, eller skapades i, ett förlorat-steg.
Ordrar
order.createdOrder skapadEn order lades upp.
order.updatedOrder ändradOrdern eller dess rader ändrades.
order.invoicedOrder faktureradOrdern gjordes om till faktura i appen.
order.cancelledOrder makuleradOrdern makulerades.

Händelserna skrivs av samma funktioner som appen och API:t använder, så ett företag som sparas i appen ger samma meddelande som ett som skapas via API:t. Import från Excel ger inga händelser.

Omförsök och paus

  • Nya försök: svarar er server inte 2xx görs nästa försök efter 1, 5 och 30 minuter, sedan 2, 6 och 12 timmar. Sammanlagt ungefär ett dygn; sedan ges det upp och utskicket får läget Gav upp i appen.
  • Försök igen för hand: under Senaste utskick i appen går ett misslyckat utskick att skicka igen med knappen Försök igen, till exempel när adressen är lagad.
  • Paus: när 20 utskick i rad har misslyckats i alla försök pausar CRMdata webhooken, och skälet står i appen. Händelser som inträffar under pausen sparas och skickas i ordning när ni startar webhooken igen (Starta i appen, eller "status": "active" i API:t), så länge de inte är äldre än 14 dagar. Utskick som redan gett upp skickas inte om av sig själva; använd Försök igen. Ett lyckat utskick nollar räkningen, och testhändelser räknas inte.
  • Stänga av: med Stäng av i appen (eller "status": "disabled" i API:t) stänger ni själva av webhooken. CRMdata stänger av den när adressen svarar 410 Gone, och skälet står då i appen och i pausedReason. Det som händer medan den är avstängd skickas inte, inte heller när ni startar den igen. En avstängd webhook räknas inte mot taket på 10. Behöver ert system det som hände under tiden hämtar ni ändringarna med API:t, se Stegvis synk.
  • Loggen: i appen ser ni de senaste utskicken per webhook med händelse, svar, antal försök och tid. Utskick och händelser sparas i 14 dagar. Svaret från er server sparas aldrig i sin helhet, bara svarskoden och ett kort felmeddelande.

Kontrollera signaturen

Huvudet CRMdata-Signature innehåller två delar: t, tidpunkten då meddelandet skickades som unix-sekunder, och v1, en HMAC-SHA256 i hex räknad med webhookens hemlighet över texten t + "." + innehållet.

CRMdata-Signature: t=1791278045,v1=5f1a9c3e7b2d4f6a8c0e1b3d5f7a9c2e4b6d8f0a1c3e5b7d9f2a4c6e8b0d1f3a
  1. Läs t och v1 ur huvudet.

  2. Kontrollera att t är högst 300 sekunder från er egen klocka. Då kan ett uppsnappat meddelande inte skickas igen senare.

  3. Räkna HMAC-SHA256 med hemligheten över t, en punkt och innehållet exakt som det kom (de råa byten, inte JSON som ni tolkat och skrivit om).

  4. Jämför med v1 med en jämförelse som tar lika lång tid oavsett var skillnaden sitter (timingSafeEqual, hmac.compare_digest). Stämmer det inte: svara 401 och ignorera meddelandet.

Färdig kod för kontrollen. Hemligheten läses ur miljövariabeln CRMDATA_WEBHOOK_SECRET, så att den inte står i koden.

import { createHmac, timingSafeEqual } from "node:crypto";

// Hemligheten som visades när webhooken skapades, sparad som miljövariabel.
const SECRET = process.env.CRMDATA_WEBHOOK_SECRET;
// Så gammalt får ett meddelande vara (sekunder): skydd mot att ett uppsnappat meddelande skickas igen.
const TOLERANCE_SECONDS = 300;

// header: värdet i huvudet CRMdata-Signature. rawBody: innehållet exakt som det kom (text eller Buffer).
export function verifyCrmdataSignature(header, rawBody) {
  const parts = Object.fromEntries(header.split(",").map((part) => part.split("=")));
  const t = Number(parts.t);
  if (!Number.isInteger(t) || Math.abs(Date.now() / 1000 - t) > TOLERANCE_SECONDS) return false;
  const expected = createHmac("sha256", SECRET).update(`${t}.`).update(rawBody).digest();
  const given = Buffer.from(parts.v1 ?? "", "hex");
  return given.length === expected.length && timingSafeEqual(given, expected);
}

// Exempel med Express. Läs innehållet som råa byte, inte som tolkad JSON: signaturen gäller texten som den kom.
app.post("/crmdata", express.raw({ type: "application/json" }), (req, res) => {
  if (!verifyCrmdataSignature(req.get("CRMdata-Signature") ?? "", req.body)) return res.sendStatus(401);
  const event = JSON.parse(req.body.toString("utf8"));
  // Har ni redan sett event.id? Svara 200 och gör inget mer.
  // Svara snabbt och gör det tunga arbetet efteråt, till exempel i en kö.
  res.sendStatus(200);
});

Har hemligheten kommit på avvägar? Ta bort webhooken i appen och skapa en ny: den får en ny hemlighet. Hemligheten går inte att visa igen i efterhand, varken för er eller för oss.

Kraven på adressen

  • Bara https. Adressen måste börja med https:// med ett giltigt certifikat. Vanlig http:// går inte.
  • Nåbar från internet. Värdnamnet måste gå att slå upp och peka på en publik adress. Adresser i lokala nät, localhost och liknande nekas, både när webhooken sparas och vid varje utskick. Vill ni prova från er egen dator kan ett verktyg som ngrok eller Cloudflare Tunnel ge er en publik https-adress.
  • Inga omdirigeringar. Ett svar med 3xx följs inte och räknas som misslyckat. Ange den slutliga adressen.
  • Svara inom 10 sekunder. Ta emot meddelandet, kontrollera signaturen, spara det och svara. Gör resten efteråt.
  • Lita på signaturen, inte på avsändarens adress. Våra utskick kan komma från olika IP-adresser. Signaturen är det som visar att meddelandet kommer från CRMdata.