A small, disposable webhook capture API. Create a temporary session, send HTTP requests to its capture URL, and retrieve the captured requests as JSON.
Hosted API: https://play.centrali.io · Usage guide · Overview and preview
Create a temporary webhook destination without an account, capture a test request, and retrieve events with a separate read token. Play is API only; use curl or provide your own viewer. Shared capacity and rate limits apply.
Play gives someone testing webhook delivery an endpoint without requiring an account or their own receiver. It is API only; consumers provide their own viewer.
Play is designed to be a self-contained service that any application can use to test webhook delivery.
curl -X POST https://play.centrali.io/sessions
# Use the captureUrl returned above:
curl -X POST '<captureUrl>' \
-H 'Content-Type: application/json' \
--data '{"example":"hello"}'
# Use the id and readToken returned at creation:
curl 'https://play.centrali.io/sessions/<session-id>/events?after=0-0' \
-H 'Authorization: Bearer <read-token>'Sessions expire after one hour by default. Bodies are limited to 64 KiB and the latest 50 events are retained. Event bodies are base64 encoded. Read the usage guide for pagination, polling, and error handling. Use synthetic data and keep both credentials private; body content is not scrubbed for secrets.
- Strict TypeScript and Hono.
- Node.js for standalone operation; a local Worker harness for compatibility tests.
- Vitest in the local Worker runtime, TypeScript checking, and Prettier formatting.
- Redis stores session metadata and credentials with fixed expiry; initial hosting targets Workers and Upstash free tiers.
The standalone Node server and Docker setup run without Cloudflare tooling and support Upstash Redis over HTTPS. Native Redis TCP support and public-launch protections remain planned.
Use Node.js 24.2 or newer (CI uses Node.js 24), npm, and Docker with Compose. No Cloudflare or Upstash account is needed for local development.
git clone https://github.com/blueinit/centrali-play.git
cd centrali-play
npm ci
docker compose up -d --wait
cp .dev.vars.example .dev.vars
npm run dev:redisThis starts a loopback-only HTTP bridge to the dedicated development Redis instance on port 6380. Keep that terminal open, then start the Worker in another terminal:
npm run devThe server listens on http://127.0.0.1:8787. In another terminal:
curl -i http://127.0.0.1:8787/health
curl -i -X POST http://127.0.0.1:8787/sessionsGET /health returns HTTP 200 with {"status":"ok"}. This is a liveness check, not a database readiness check. POST /sessions returns HTTP 201 with an ID, capture URL, read token, and fixed expiry, as described in the session contract. Both responses disable caching.
Copy the returned capture URL into this command using synthetic data:
curl -i -X POST '<captureUrl>' \
-H 'Content-Type: application/json' \
--data '{"example":"hello"}'A successful capture returns 204 after storage confirms the write. Bodies are limited to 64 KiB, common credential headers are redacted, and the latest 50 events share the session deadline. See the capture contract for all limits and methods.
Use the session ID and separate read token from creation to retrieve captures:
curl 'http://127.0.0.1:8787/sessions/<session-id>/events?after=0-0' \
-H 'Authorization: Bearer <read-token>'The JSON response contains base64 bodies and a nextCursor. Pass that cursor as after on the next request to read only newer events. Pages contain up to 10 events within a 256 KiB response limit. Follow hasMore for additional pages; back off between empty polls as described in the read contract. Reads never extend expiry. Unknown routes return JSON 404 responses; unsupported capture and read methods return 405.
Stop the Worker and bridge with Ctrl+C, then run docker compose down. Development Redis has no persistent volume; removing its container discards its data.
The HTTP bridge is development tooling, not a production Redis gateway. It accepts Redis commands using a public placeholder token. Never expose it, use production credentials with it, or point it at application data.
docker compose up -d --wait
npm run checkThis runs formatting and TypeScript checks, Worker and Node tests against local Redis, and both runtime builds. Tests start and stop their own HTTP bridge; npm run dev:redis is not required for them. It does not deploy or create hosted resources.
Individual commands and repository structure are documented in Contributing.
- Running Play: standalone Node/Docker setup, Upstash configuration, and shutdown.
- Design: architecture, proposed API, and open decisions.
- Session contract: creation response, credentials, expiry, and configuration.
- Capture contract: methods, limits, redaction, binary encoding, and storage.
- Event-read contract: authorization, cursor pagination, response bounds, and polling.
- Per-session limits: capture/read allowances, configuration, and safe 429 responses.
- Global session admission: creation limits, shared capacity, pending slots, and safe exhaustion.
- Monthly workload budgets: shared reservations, configuration, denial caching, and safe exhaustion.
- Abuse-control contract: implemented protections and proposed edge controls and privacy rules.
- Roadmap: planned capabilities and release readiness.
- Contributing: changes, code expectations, and review.
- Maintaining: ownership, releases, deployment, and incidents.
- Security: private reporting and data handling.
Do not send production secrets or personal data to the hosted service. Capture URLs and read tokens are sensitive capabilities.
MIT. Contributions use the same license.