Skip to content

Delivery and retries

  • At least once. A 2xx response counts as delivered. Any other status, a connection error or no response within 10 seconds counts as a failure.
  • Retries. After a failure Kasskeep retries after 1 minute, 5 minutes, 30 minutes, 2 hours, 12 hours, 24 hours and 24 hours: eight attempts over about two and a half days. After that the event is marked failed and is still available from the event log.
  • Stable ids. The event id is derived from the app and the store event, so the same change arriving through a client submission, a store notification and reconciliation has one id.
  • No ordering. Events can arrive out of order. Use created_at and the event fields.
  • Events are only delivered to the app’s current webhook_url. An app without a URL keeps its events in the log only.

GET /v1/events returns the app’s events in the order they were created. Use it to backfill after downtime or to process events without webhooks.

Terminal window
curl "https://api.kasskeep.com/v1/events?after=0&limit=100" -H "Authorization: Bearer sk_..."
{ "events": [ { "id": "evt_...", "type": "purchase", "...": "..." } ], "next_cursor": "42", "has_more": false }

Pass next_cursor as after on the next call. The cursor is opaque. limit is 1 to 500, default 100. Test events are not in the log.

Terminal window
curl -X POST https://api.kasskeep.com/v1/admin/tenants/<tenant_id>/apps/<app_id>/webhooks/test \
-H "Authorization: Bearer kkp_..."

Kasskeep signs a test event with the current webhook secret, sends it with the same headers as a real event and waits up to 10 seconds:

{ "event_id": "evt_...", "sent_at": "2026-11-06T08:00:00.000Z", "ok": true, "status": 200, "duration_ms": 87, "response_body": "ok", "error": null }

response_body is the first 500 bytes of your response with keys, tokens and signatures replaced by (redacted). When the connection fails, status is null and error explains why. Test deliveries are not retried and not written to the log. Each app can send 10 per minute (429 rate_limited beyond that), and an app without a webhook URL gets 422 webhook_url_not_configured. Requires the webhooks.test permission (developer and above).