Skip to Content
How It WorksEvent Ingestion

Event Ingestion

Endpoint

GET /api/v1/beet/:token POST /api/v1/beet/:token

Both methods are accepted. GET is used for image beacon integrations; POST is used for JavaScript fetch calls. The response is always a 1×1 transparent GIF (image/gif).

Authentication

Each beet has a unique opaque token generated at creation time. The token is passed as a URL path parameter — there are no headers or request bodies required for a minimal ping.

Tokens can be rotated from the beet detail page. The old token becomes invalid immediately on rotation.

Rate limiting

Ingestion requests are rate-limited per token using Upstash Redis (sliding window, 60 requests per 10 seconds). Requests that exceed the limit receive a 429 Too Many Requests response. The 1×1 GIF response body is still returned to avoid breaking image beacon integrations in browsers.

Heartbeet is designed for low-frequency business events (checkouts, cron jobs, webhooks), not high-frequency telemetry. If you need to track thousands of events per second, Heartbeet is not the right tool.

Optional metadata

You can POST a JSON body with a value field for future use:

fetch('/api/v1/beet/YOUR_TOKEN', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ value: 42 }), })

The value field is stored but not currently used in anomaly detection. It is reserved for future numeric threshold features.

Storage

Each successful event is written to the beet_events table, which is partitioned by received_at (monthly partitions). This keeps queries fast as data volume grows and allows efficient bulk deletion during retention cleanup.

Data retention

Events older than the plan’s retention window are deleted by the cron job on each run:

PlanRetention
Free30 days
Starter1 year
Pro3 years
Enterprise3 years