savrsoft

API-dokumentation

Ett enkelt REST API för att läsa och skriva din cateringdata, plus signerade webhooks för händelser i realtid. Skapa en nyckel under Developer i appen.

Autentisering

Alla API-anrop använder en API-nyckel som bearer-token. Skapa en i appen under Developer → API keys. Nycklar är antingen skrivskyddade eller läs/skriv.

curl https://savrsoft.com/api/v1/events \
  -H "Authorization: Bearer savr_live_your_key_here"

Bas-URL: https://savrsoft.com/api/v1 · Alla svar är i JSON. Fel returneras som { "error": "…" } med en 4xx/5xx-statuskod.

Statuskoder

KodNär du får den
200Lyckad läsning.
201Skapad utan problem. Innehållet är { "id": 42 } — hämta posten om du behöver resten av informationen.
400Ett obligatoriskt fält saknas, t.ex. { "error": "name is required" }, eller så gick det inte att läsa en pagineringscursor.
401Ingen API-nyckel, en felaktig sådan, eller en nyckel som har återkallats.
403En skrivskyddad nyckel användes för en skrivåtgärd. Skapa en läs-/skrivnyckel under Utvecklare → API-nycklar.
404Posten finns inte, eller tillhör en annan organisation — de två fallen är medvetet omöjliga att skilja åt. Returneras också för en okänd sökväg eller metod.

Denna API:s omfattning

API:et är endast läsning och skapande. Det finns inga DELETE, PUT eller PATCH -slutpunkter — en förfrågan som använder en sådan returnerar 404 Unknown endpoint, precis som för alla okända sökvägar. Radering och redigering görs i appen, så en integration kan inte förstöra en cateringfirmas poster. Om du behöver skrivåtkomst utöver att skapa, berätta för oss vad du bygger.

Sidnumrering

Varje listslutpunkt är sidnumrerad. Skicka med limit (standard 100, max 500) och följ next_cursor tills has_more är false:

{
  "data": [ ... ],
  "has_more": true,
  "next_cursor": "eyJuYW1lIjoiQWNtZSIsImlkIjo0Mn0"
}

Skicka tillbaka markören direkt för att få nästa sida. Behandla den som ogenomskinlig — kodningen kan komma att ändras:

curl "https://savrsoft.com/api/v1/clients?limit=100&cursor=eyJuYW1lIjoiQWNtZSIsImlkIjo0Mn0" \
  -H "Authorization: Bearer savr_live_your_key_here"

Sidnumrering är förankrad till den senaste raden du tog emot, inte till en offset, så rader som skapas eller raderas medan du bläddrar kommer inte att göra att du hoppar över eller upprepar en post. En markör förblir giltig på obestämd tid.

ParameterBeteende
limit1–500. Om värdet saknas, är noll, negativt eller icke-numeriskt används 100 som standard; allt över 500 begränsas till 500.
cursornext_cursor från föregående sida. Utelämna den för den första sidan. En markör som inte kan läsas — skadad, eller från en annan endpoint — returnerar 400 Invalid cursor istället för att tyst börja om från början.

Ordning: /events och /invoices nyast först; /recipes och /clients efter namn, där oavgjort avgörs av id så att sidnumreringen förblir stabil när namn upprepas.

Endpoints

GET/v1/me

Din organisation (id, namn, valuta).

GET/v1/events

Lista evenemang, nyast först. Paginerad — se Sidnumrering ovan.

GET/v1/events/{id}

Ett event med tillhörande rätter.

POST/v1/events · kräver läs-/skrivbehörighet

Skapa ett event. Body:

{ "name": "Acme holiday party", "event_date": "2026-12-18",
  "guests": 120, "price_per_head": 55, "event_type": "corporate" }
GET/v1/recipes · GET/v1/recipes/{id}

Lista recept (med allergener & kostflaggor), eller hämta ett recept med ingredienser. Listan är paginerad och sorterad efter namn.

GET/v1/clients · POST/v1/clients

Lista kunder (paginerad, efter namn) eller skapa en ny. Body för att skapa: { "name": "...", "email": "...", "phone": "...", "company": "..." }

GET/v1/invoices · GET/v1/invoices/{id}

Lista fakturor med beräknade totalsummor, nyaste först, eller hämta en faktura med radposter. Listan är paginerad.

Webhooks

Registrera en endpoint under Developer → Webhooks. Vi skickar en POST med en JSON-payload när events inträffar:

{
  "id": "evt_abc123",
  "type": "event.inquiry",
  "created_at": "2026-07-17T18:20:00.000Z",
  "data": { "id": 42, "name": "Corporate lunch — Dana Ruiz", ... }
}

Eventtyper

TypUtlöses när
event.createdEtt event skapas
event.inquiryEn ny cateringförfrågan kommer in online
invoice.sentEn faktura markeras som skickad
invoice.paidEn faktura markeras som betald
proposal.approvedEn kund godkänner ett förslag
client.createdEn kund skapas

Verifiera signaturer

Varje leverans innehåller en x-savrsoft-signature header: HMAC-SHA256 av den råa förfrågningskroppen, signerad med din webhook-signeringsnyckel. Beräkna samma värde och jämför:

// Node.js
const crypto = require('crypto');
const sig = crypto.createHmac('sha256', SIGNING_SECRET)
  .update(rawBody).digest('hex');
if (sig !== req.headers['x-savrsoft-signature']) reject();
Integritet · Säkerhet · Villkor · Frågor? savrsoft.com · Bygg cateringintegrationer på minuter.