Quickstart
From your app
to your agent.
Deploy a Worker to your own Cloudflare account, connect the CLI, and keep your events in one local database. Install the CLI with one command, on macOS or Linux.
Put the Worker in your account.
One Worker, two Durable Object classes and an R2 bucket, deployed by slurp cloud init. You need a Cloudflare account (the Free plan is enough to start) and Node 20+. The dialog has the commands.
Make a home for your events.
Install the CLI with the shell command or npm. slurp cloud init deploys your Worker and connects this computer to it. Already have one? slurp connect <url> --token-stdin checks its admin token and remembers it. Setup finds DuckDB or offers to install it. Init creates or selects an app by name. Run slurp projects to list registered projects.
curl -LsSf https://slurp.run/install | sh
# or: npm install -g @hitslop/slurp
slurp cloud init
slurp setup
cd /path/to/your/app
slurp init --name "My app"slurp init opens a private offline quickstart with your project’s SDK instructions. Rerun init to refresh that page.
Send your first event.
Install the SDK from npm, then paste the snippet slurp init shows for your app: it has your two values: the ingest URL of your Worker and the publishable key that slurp init created with the project. Publishable keys are ingest-only, so they are safe in a web page or an app. Lost them? slurp project setup PROJECT prints them again, and slurp project key create PROJECT --scope publishable --source ios makes one key per source (web, ios, github), and the source is stamped on every event as sender.
npm install @hitslop/slurp-sdkimport { init, track, flush } from '@hitslop/slurp-sdk';
init({
endpoint: 'YOUR_INGEST_URL',
key: 'YOUR_PUBLISHABLE_KEY',
});
track('signed_up', { plan: 'pro' });
await flush(); // Node: flush before exitingUser feedback is just another event: track('feedback', { message, rating }); Your agent finds it later with SQL.
Test from your terminal.
Inside your app or a subfolder, Slurp uses the nearest project binding. It asks your Worker for the publishable key of the cli source, so it needs the saved admin connection. These events carry sender = 'cli'.
slurp send signed_up --user-id demo_alice --data '{"demo":true}'
slurp sync --nowSending confirms durable acceptance. Events reach slurp sync after your Worker next publishes an archive, about every 10 minutes by default (earlier when 8 MB are buffered). --now asks the Worker to publish first, so events sent a moment ago are included; it needs the admin token.
Send events over HTTP.
Any language can POST to /v1/events on your Worker. The body is one JSON object, or one object per line (NDJSON). Only event is required. Put your publishable key in ?key= or in Authorization: Bearer. Tools that send webhooks (GitHub, Stripe, anything) use their own endpoint.
# Any language. One JSON object is a valid body and only "event" is required.
curl -X POST 'YOUR_INGEST_URL?key=YOUR_PUBLISHABLE_KEY' --data-binary '{"event":"signed_up"}'
# Add an "id" so a retry is safe: the same id from the same source is stored once. Several records: one JSON object per line.
curl -X POST 'YOUR_INGEST_URL?key=YOUR_PUBLISHABLE_KEY' --data-binary $'{"id":"evt_1","event":"signed_up","user_id":"user_42","data":{"plan":"pro"}}\n{"id":"evt_2","event":"project_created","user_id":"user_42"}\n'
# The key can also go in an "Authorization: Bearer YOUR_PUBLISHABLE_KEY" header.A 200 with {"ok":true,"accepted":1} means the event is durable. If any line is invalid, nothing is stored and the 400 lists every bad line. Records without an id are each a new event, so send an id to make a retry safe: the same id from the same source is stored once. id, type, timestamp and data are optional; the import fills in a missing timestamp with the arrival time.
Webhooks.
Point GitHub, Stripe, RevenueCat or any tool that can POST at your Worker. Each gets its own named key, so its events carry sender = 'github' and the payload is stored whole as the event's data. Releases and deployments show up in a releases view you can join to your product events.
slurp project webhook PROJECT github
slurp project webhook PROJECT stripe --secret whsec_…
slurp project webhook PROJECT revenuecat
slurp project webhook PROJECT genericStripe chooses its own signing secret, so you give it to Slurp. Details: webhooks.md.
Bring the events home.
slurp init --backend YOUR_BACKEND --connect YOUR_PROJECT_ID
slurp sync
slurp health # anything the import set aside (conflicts, invalid lines, retention gaps)
slurp sql 'SELECT event, count(*) AS n FROM events GROUP BY event'Run slurp sync to download new archives from your Worker into your local DuckDB database. Recently accepted events may still be waiting for the next archive: slurp sync --now publishes first (admin token). Sync never stops on a bad event: an id reused with different content, a line of the wrong shape or an archive deleted by retention becomes a row in _slurp.problems, and slurp health reports them. Close open DuckDB sessions before syncing.
Give your agent the context.
slurp agent setup --out .agents/skills/slurp --allAsk your local coding agent to inspect the workspace and query its events. For a bot running on another machine, create a separate revocable read key:
slurp --backend YOUR_BACKEND project key create YOUR_PROJECT_ID --scope secret --name grok # --name labels a secret keyTransfer the returned key through the bot’s secret store as SLURP_TOKEN, then run these steps on its machine:
slurp agent setup --out .agents/skills/slurp
# Put the bot read key in its secret store as SLURP_TOKEN.
slurp init --backend YOUR_BACKEND --connect YOUR_PROJECT_ID
slurp syncKeep keys out of URLs, reports, and skill files. Revoke a key with slurp project key revoke.
Or connect an AI client over MCP
slurp mcp lets Claude Code, Cursor, Codex, Claude Desktop or Windsurf read your events directly: describe the schema, run read-only SQL (in a sandbox that cannot read local files), sync and build reports. Sending events is off unless you add --allow-send.
# Let an AI client read this project's events over MCP (add --allow-send to let it send events too).
claude mcp add slurp -- slurp mcp --project /path/to/your/project
# Cursor, Claude Desktop, Windsurf (JSON) and Codex (TOML): see https://github.com/hitSlop/slurp/blob/master/docs/integrations.mdPost reports to Slack or Discord
# Post a report to Slack (bot token) or Discord (webhook). Credentials come from the environment.
slurp report build report.md --out ./report --png
SLACK_BOT_TOKEN=xoxb-... slurp notify slack --channel C0123ABCD --text "Weekly report" --file ./report/report.pngSetup for every client, the tools, the sandbox and a cron recipe: docs/integrations.md.
Keep the query with the finding.
Ask your agent to create report.md using the repository’s examples/events.md as a reference. Reports combine Markdown, named SQL queries, and metric, table, or chart blocks.
slurp report check report.md
slurp report build report.md --out ./report --png --pdf
slurp report open ./reportHTML embeds charts and fonts. PNG and PDF are ready to share. Review the included data before sharing a report.