Push sales and inventory into Kesper from any system — custom POS, Zapier, in-house scripts, brand-new restaurants on platforms we don't natively support.
Every ingest call needs a Bearer header with your API key. Keys look likekesper_<48 hex chars>and are tied to a single store.
Authorization: Bearer kesper_<48hex>
Content-Type: application/jsonPlaintext keys are stored SHA-256-hashed at rest. If you lose a key, create a new one — there's no recovery path.
/api/ingest/transactionsSubmit a batch of sales transactions. Max 1000 per request.
Auth: API key
/api/ingest/inventorySubmit a current inventory snapshot. Max 5000 items per request. Replaces the previous snapshot.
Auth: API key
/api/ingest/keysCreate a new API key. Returns plaintext once; save it immediately.
Auth: Session (in-dashboard)
/api/ingest/keys?storeId=…List API keys for a store (suffixes + metadata only — no plaintext).
Auth: Session (in-dashboard)
/api/ingest/keys/:idSoft-revoke a key. Future requests with it return 401 immediately.
Auth: Session (in-dashboard)
Body is a JSON array of transaction objects. Required fields: transaction_id, timestamp (ISO 8601), items (array), total.
[
{
"transaction_id": "tx_2026_05_12_001",
"timestamp": "2026-05-12T15:42:00Z",
"items": [
{
"sku": "latte_12oz",
"name": "12oz Latte",
"qty": 1,
"unit_price": 5.50,
"cost": 1.20,
"total": 5.50
}
],
"total": 5.50,
"payment_method": "card"
}
]Body is a JSON array of inventory items. Required fields: sku, name, qty_on_hand.
[
{
"sku": "latte_12oz",
"name": "12oz Latte",
"qty_on_hand": 87,
"qty_on_order": 0,
"cost": 1.20,
"sell_price": 5.50,
"category": "Beverages",
"expiry_date": "2026-06-15",
"last_sold": "2026-05-12T15:42:00Z"
}
]Replace $KEY with your plaintext API key.
# Push 1 transaction
curl -X POST https://kesper-production.up.railway.app/api/ingest/transactions \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '[{"transaction_id":"tx1","timestamp":"2026-05-12T15:00:00Z","items":[{"sku":"latte","name":"12oz Latte","qty":1,"unit_price":5.5,"cost":1.2,"total":5.5}],"total":5.5,"payment_method":"card"}]'
# Push an inventory snapshot
curl -X POST https://kesper-production.up.railway.app/api/ingest/inventory \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '[{"sku":"latte","name":"12oz Latte","qty_on_hand":87,"qty_on_order":0,"cost":1.2,"sell_price":5.5,"category":"Beverages"}]'Success responses use HTTP 200 and a small JSON body confirming the count ingested:
{ "ok": true, "ingested": 42, "storeId": "your_store_id" }Common errors:
401 Bearer API key required — missing Authorization header.401 Invalid or revoked API key — key not found or revoked.400 Body must be a JSON array — wrong body shape.400 Item N is missing required fields — schema violation; fix the listed item index.400 Max 1000 transactions / 5000 items — split into multiple calls.429 Ingest rate limited — max 120 requests per minute per key. Back off and retry.RateLimit-* response headers are returned so you can pace your client.Ingested data flows into the same persistence layer as our native connectors. The agents pick it up on their next scheduled run:
Questions about the API, schemas, or integration patterns? Email business@kesper.io.