savrsoft

Dokumentasi API

REST API sederhana untuk membaca dan menulis data katering Anda, ditambah webhook bertanda tangan untuk event real-time. Buat key di bawah Developer di aplikasi.

Autentikasi

Semua permintaan API menggunakan API key sebagai bearer token. Buat satu di aplikasi di bawah Developer → API keys. Key bisa berupa read-only atau read/write.

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

Base URL: https://savrsoft.com/api/v1 · Semua respons berupa JSON. Error akan mengembalikan { "error": "…" } dengan status 4xx/5xx.

Kode status

KodeKapan Anda mendapatkannya
200Berhasil membaca.
201Berhasil dibuat. Body-nya adalah { "id": 42 } — ambil record tersebut jika Anda memerlukan sisa datanya.
400Ada field wajib yang hilang, misalnya { "error": "name is required" }, atau cursor pagination tidak dapat dibaca.
401Tidak ada kunci API, kunci yang tidak valid, atau kunci yang telah dicabut.
403Kunci hanya-baca digunakan untuk operasi tulis. Buat kunci baca/tulis di Developer → API keys.
404Rekaman tersebut tidak ada, atau milik organisasi lain — keduanya sengaja dibuat tidak dapat dibedakan. Juga dikembalikan untuk path atau method yang tidak dikenali.

Cakupan API ini

API ini bersifat hanya baca dan buat. Tidak ada endpoint DELETE, PUT atau PATCH — permintaan yang menggunakan salah satunya akan mengembalikan 404 Unknown endpoint, sama seperti path yang tidak dikenali. Penghapusan dan pengeditan dilakukan di dalam aplikasi, sehingga integrasi tidak dapat menghapus data milik caterer. Jika Anda memerlukan akses tulis di luar pembuatan data, beri tahu kami apa yang sedang Anda bangun.

Paginasi

Setiap endpoint daftar menggunakan paginasi. Kirimkan limit (default 100, maksimum 500) dan ikuti next_cursor hingga has_more bernilai false:

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

Kirimkan kembali cursor tersebut untuk mendapatkan halaman berikutnya. Perlakukan sebagai nilai buram — encoding-nya bisa berubah sewaktu-waktu:

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

Penomoran halaman berpatokan pada baris terakhir yang Anda terima, bukan pada offset, sehingga baris yang dibuat atau dihapus saat Anda membuka halaman tidak akan membuat Anda melewati atau mengulang suatu data. Sebuah cursor akan tetap valid tanpa batas waktu.

ParameterPerilaku
limit1–500. Jika kosong, nol, negatif, atau bukan angka, akan default ke 100; nilai di atas 500 akan dibatasi menjadi 500.
cursornext_cursor dari halaman sebelumnya. Abaikan untuk halaman pertama. Cursor yang tidak dapat dibaca — rusak, atau berasal dari endpoint yang berbeda — akan mengembalikan 400 Invalid cursor alih-alih diam-diam memulai ulang dari awal.

Urutan: /events dan /invoices terbaru lebih dulu; /recipes dan /clients berdasarkan nama, dengan urutan yang sama diselesaikan berdasarkan id agar penomoran halaman tetap stabil saat ada nama yang berulang.

Endpoint

GET/v1/me

Organisasi Anda (id, name, currency).

GET/v1/events

Menampilkan daftar events, terbaru lebih dulu. Menggunakan penomoran halaman — lihat Penomoran Halaman di atas.

GET/v1/events/{id}

Satu acara beserta hidangannya.

POST/v1/events · memerlukan read/write

Buat acara baru. 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}

Menampilkan daftar resep (lengkap dengan alergen & tanda diet), atau satu resep beserta bahan-bahannya. Daftar ini dipaginasi dan diurutkan berdasarkan nama.

GET/v1/clients · POST/v1/clients

Menampilkan daftar klien (dipaginasi, berdasarkan nama) atau membuat klien baru. Body untuk membuat: { "name": "...", "email": "...", "phone": "...", "company": "..." }

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

Menampilkan daftar invoice beserta total yang sudah dihitung, terbaru lebih dulu, atau satu invoice beserta rincian itemnya. Daftar ini dipaginasi.

Webhooks

Daftarkan endpoint di bawah Developer → Webhooks. Kami akan POST payload JSON saat suatu event terjadi:

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

Jenis event

TipeTerpicu saat
event.createdSebuah acara dibuat
event.inquiryPermintaan katering online baru masuk
invoice.sentInvoice ditandai terkirim
invoice.paidInvoice ditandai lunas
proposal.approvedKlien menyetujui proposal
client.createdKlien baru dibuat

Memverifikasi tanda tangan

Setiap pengiriman menyertakan header x-savrsoft-signature : HMAC-SHA256 dari isi request mentah, menggunakan kunci penandatanganan webhook Anda. Hitung nilai yang sama dan bandingkan:

// 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();
Privasi · Keamanan · Ketentuan · Ada pertanyaan? savrsoft.com · Bangun integrasi katering dalam hitungan menit.