savrsoft

API ドキュメント

ケータリングデータの読み書きが行えるシンプルなREST APIに加え、リアルタイムイベント通知のための署名付きWebhookも提供します。キーの作成は 開発者 (アプリ内)から行えます。

認証

すべてのAPIリクエストは、APIキーをベアラートークンとして使用します。アプリ内の 開発者 → APIキーから作成できます。 読み取り専用 または 読み取り/書き込み.

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

ベースURL: https://savrsoft.com/api/v1 ・すべてのレスポンスはJSON形式です。エラー時は { "error": "…" } のような4xx/5xxステータスが返されます。

ステータスコード

コード発生タイミング
200読み取り成功。
201作成成功。ボディは { "id": 42 } です — 残りの情報が必要な場合はレコードを取得してください。
400必須フィールドが未入力です。例: { "error": "name is required" }、またはページネーションカーソルが読み取れませんでした。
401APIキーがない、不正な形式である、または失効しているキーです。
403読み取り専用キーで書き込み操作が行われました。読み書き可能なキーを以下から作成してください 開発者 → APIキー.
404レコードが存在しないか、他の組織に属しています——この2つのケースは意図的に区別されません。認識できないパスやメソッドの場合も同様に返されます。

このAPIの範囲

APIは 読み取りと作成のみです。 DELETE, PUT または PATCH のエンドポイントは存在しません——これらを使用したリクエストは、認識できないパスと同様に 404 Unknown endpointを返します。削除や 編集はアプリ内で行うため、連携先がケータリング業者のレコードを破壊することはできません。作成以外の書き込みアクセスが必要な場合は、 作ろうとしているものを教えてください.

ページネーション

すべての一覧エンドポイントはページネーションに対応しています。次を渡してください: limit (デフォルト 100、最大 500)を渡し、 に従ってください next_cursor まで has_morefalse:

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

カーソルはそのまま返して次のページを取得してください。中身は不透明なものとして扱ってください — エンコード方式は変更される可能性があります:

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

ページネーションは、オフセットではなく最後に受け取った行を基準にしています。そのため、ページ取得中に行が作成または削除されても、レコードをスキップしたり重複して取得したりすることはありません。カーソルは無期限に有効です。

パラメータ動作
limit1〜500。未指定、ゼロ、負の値、または数値以外の場合は100にフォールバックします。500を超える値は500に制限されます。
cursornext_cursor 前のページからの値です。最初のページでは省略してください。読み取れないカーソル(破損している、または別のエンドポイントのもの)を指定した場合は、 400 Invalid cursor を返し、黙って最初から再開することはありません。

並び順: /events/invoices は新しい順、 /recipes/clients は名前順で、名前が重複する場合はidで順序が確定するため、名前が重複してもページングは安定して動作します。

エンドポイント

GET/v1/me

組織情報(id、名前、通貨)。

GET/v1/events

イベント一覧を新しい順に取得します。ページネーション対応 — 詳細は上記の ページネーション をご覧ください。

GET/v1/events/{id}

料理付きの単一イベント。

POST/v1/events · 読み取り/書き込み権限が必要

イベントを作成します。ボディ:

{ "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}

レシピ一覧(アレルゲン&食事制限フラグ付き)、または材料付きの単一レシピを取得します。一覧はページネーションされ、名前順に並びます。

GET/v1/clients · POST/v1/clients

顧客一覧(ページネーション、名前順)を取得、または新規作成します。作成ボディ: { "name": "...", "email": "...", "phone": "...", "company": "..." }

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

計算済みの合計金額付き請求書一覧を新しい順に取得、または明細付きの単一請求書を取得します。一覧はページネーションされます。

Webhooks

エンドポイントを 開発者 → Webhooksに登録してください。イベント発生時に POST でJSONペイロードを送信します:

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

イベントタイプ

タイプ発火タイミング
event.createdイベントが作成された
event.inquiry新しいオンラインケータリングリクエストが届いた
invoice.sent請求書が送信済みとしてマークされた
invoice.paid請求書が支払い済みとしてマークされた
proposal.approvedクライアントが提案を承認した
client.createdクライアントが作成された

署名の検証

各配信には x-savrsoft-signature ヘッダーが含まれます:これは生のリクエストボディをwebhook署名シークレットで鍵付けしたHMAC-SHA256です。同様に計算して比較してください:

// 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();
プライバシー · セキュリティ · 利用規約 · ご質問は? savrsoft.com · 数分でケータリング連携を構築。