savrsoft

Dokumentacja API

Proste API REST do odczytu i zapisu danych cateringowych, wraz z podpisywanymi webhookami dla zdarzeń w czasie rzeczywistym. Utwórz klucz w zakładce Developer w aplikacji.

Uwierzytelnianie

Wszystkie żądania API wykorzystują klucz API jako token typu bearer. Utwórz go w aplikacji w sekcji Developer → API keys. Klucze mogą być tylko do odczytu lub do odczytu i zapisu.

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

Adres bazowy: https://savrsoft.com/api/v1 · Wszystkie odpowiedzi są w formacie JSON. Błędy zwracają { "error": "…" } ze statusem 4xx/5xx.

Kody statusu

KodKiedy go otrzymujesz
200Odczyt zakończony powodzeniem.
201Utworzono pomyślnie. Treść odpowiedzi to { "id": 42 } — pobierz rekord, jeśli potrzebujesz reszty danych.
400Brakuje wymaganego pola, np. { "error": "name is required" }, lub nie udało się odczytać kursora paginacji.
401Brak klucza API, klucz nieprawidłowy lub klucz, który został unieważniony.
403Użyto klucza tylko do odczytu przy operacji zapisu. Utwórz klucz do odczytu i zapisu w Developer → API keys.
404Rekord nie istnieje lub należy do innej organizacji — te dwa przypadki są celowo nierozróżnialne. Ten sam błąd zwracany jest też dla nierozpoznanej ścieżki lub metody.

Zakres tego API

API umożliwia tylko odczyt i tworzenie. Nie ma tu DELETE, PUT ani PATCH punktów końcowych — żądanie z ich użyciem zwraca 404 Unknown endpoint, tak samo jak każda nierozpoznana ścieżka. Usuwanie i edycja odbywają się w aplikacji, dzięki czemu integracja nie może zniszczyć danych cateringu. Jeśli potrzebujesz dostępu do zapisu wykraczającego poza tworzenie, napisz nam, co budujesz.

Paginacja

Każdy punkt końcowy listy jest stronicowany. Przekaż limit (domyślnie 100, maksymalnie 500) i podążaj za next_cursorhas_more będzie false:

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

Przekaż kursor bezpośrednio, aby pobrać następną stronę. Traktuj go jako nieprzejrzysty ciąg — kodowanie może się zmienić:

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

Stronicowanie jest zakotwiczone względem ostatniego otrzymanego wiersza, a nie przesunięcia, więc wiersze utworzone lub usunięte w trakcie stronicowania nie spowodują pominięcia ani powtórzenia rekordu. Kursor pozostaje ważny bezterminowo.

ParametrZachowanie
limit1–500. Brak wartości, zero, wartość ujemna lub nienumeryczna powoduje przyjęcie wartości domyślnej 100; wszystko powyżej 500 jest ograniczane do 500.
cursornext_cursor z poprzedniej strony. Pomiń dla pierwszej strony. Kursor, którego nie można odczytać — uszkodzony lub pochodzący z innego endpointu — zwraca 400 Invalid cursor zamiast po cichu zaczynać od początku.

Kolejność: /events i /invoices od najnowszych; /recipes i /clients alfabetycznie według nazwy, a remisy są rozstrzygane według id, dzięki czemu stronicowanie pozostaje stabilne, gdy nazwy się powtarzają.

Endpointy

GET/v1/me

Twoja organizacja (id, nazwa, waluta).

GET/v1/events

Lista wydarzeń, od najnowszych. Stronicowane — patrz Stronicowanie powyżej.

GET/v1/events/{id}

Jedno wydarzenie z jego daniami.

POST/v1/events · wymaga uprawnień odczytu/zapisu

Utwórz wydarzenie. Treść:

{ "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 przepisów (z alergenami i oznaczeniami diet) lub jeden przepis ze składnikami. Lista jest stronicowana i posortowana alfabetycznie.

GET/v1/clients · POST/v1/clients

Lista klientów (stronicowana, alfabetycznie) lub utworzenie nowego. Treść żądania: { "name": "...", "email": "...", "phone": "...", "company": "..." }

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

Lista faktur z wyliczonymi sumami, od najnowszych, lub jedna faktura z pozycjami. Lista jest stronicowana.

Webhooki

Zarejestruj endpoint w sekcji Developer → Webhooks. Wysyłamy POST z danymi JSON, gdy wystąpi zdarzenie:

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

Typy zdarzeń

TypUruchamiane, gdy
event.createdZdarzenie zostaje utworzone
event.inquiryWpływa nowe zapytanie cateringowe online
invoice.sentFaktura zostaje oznaczona jako wysłana
invoice.paidFaktura zostaje oznaczona jako opłacona
proposal.approvedKlient zatwierdza ofertę
client.createdKlient zostaje utworzony

Weryfikacja podpisów

Każda dostawa zawiera nagłówek x-savrsoft-signature : HMAC-SHA256 surowej treści żądania, podpisany kluczem webhooka. Oblicz to samo i porównaj:

// 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();
Prywatność · Bezpieczeństwo · Warunki · Masz pytania? savrsoft.com · Twórz integracje cateringowe w kilka minut.