For developers
POST to a URL. Get a typed BigQuery table.
No SDK to install. No wrappers to maintain. Hooktopus is a single HTTPS endpoint per stream and a small REST API to manage destinations. The platform is documented top-to-bottom and public-facing — what we ship is what you read.
OpenAPI 3.1 spec · Stainless-generated TS & Python clients · public Postman collection.
# Send any JSON to your endpoint
curl -X POST "https://in.hooktopus.io/ws_abc123/stripe" \
-H 'content-type: application/json' \
-H 'authorization: t_••••' \
-d '{
"id": "evt_3Pkx9aL",
"type": "charge.succeeded",
"data": { "object": { "amount": 12999, "currency": "usd" } }
}'
# Response (202)
# {"ok":true,"event_id":"019e326c-96f5-7a5f-b104-17239aa5bea4"}
Receive
What we promise on ingest.
UUIDv7 event IDs
Every event gets a 128-bit time-ordered ID. Sortable. Deduplicable. Stable across replays. Returned in the 202 response body and stamped on the BigQuery row.
Canonical archive
Body, headers, source IP, content type — written to R2 as one JSON object ws_/yyyy/mm/dd/hh/endpoint/event.json before we 202. If BigQuery is down, your events still exist.
At-least-once delivery
Queues batch up to 100 events / 30s. Failed BQ writes go to a dead-letter queue with the full error. event_id doubles as the BQ unique key — dedupe is free.
Signature verification
Hookdeck handles Stripe, GitHub, Shopify, HubSpot, Twilio, Linear, and ~25 more signature schemes out of the box. Custom sources can use HMAC-SHA256 with your secret.
Replay-from-anywhere
Re-write any time range from R2 back through the destination writer. Useful after BQ outages, schema changes, or just experimenting in dev.
Honest error semantics
4xx if you sent something we can't parse — payload still archived to a DLQ in R2 either way. 5xx never silently drops; the source's retry logic does its job.
Manage
A small REST API. No SDK required.
POST /v1/endpoints HTTP/1.1
Host: api.hooktopus.io
Authorization: Bearer hk_live_••••
Content-Type: application/json
{
"workspace": "ws_abc123",
"name": "stripe",
"source": "stripe",
"hmac_secret": null
}
POST /v1/endpoints/ep_stripe_x/dbt-export HTTP/1.1
Host: api.hooktopus.io
Authorization: Bearer hk_live_••••
Content-Type: application/json
{
"min_occurrence_pct": 1.0,
"include": ["data.object.amount", "type"]
}
# Returns a presigned ZIP URL valid for 5 minutes.
GET /v1/endpoints/ep_stripe_x/events?limit=50 HTTP/1.1
Host: api.hooktopus.io
Authorization: Bearer hk_live_••••
POST /v1/replay HTTP/1.1
Host: api.hooktopus.io
Authorization: Bearer hk_live_••••
Content-Type: application/json
{
"endpoint_id": "ep_stripe_x",
"from": "2026-05-10T00:00:00Z",
"to": "2026-05-11T00:00:00Z",
"destination_id": "dst_bq_prod"
}
Full reference at /docs/api or via the public OpenAPI spec at api.hooktopus.io/openapi.json.
The CLI
On the way (v1.2). Sneak peek:
# Tail events from any endpoint, like wrangler tail
hooktopus events tail --endpoint stripe
# Sample 50 events into a local file
hooktopus events sample stripe --limit 50 > events.ndjson
# Generate dbt files locally
hooktopus dbt generate stripe --out ./models/staging/hooktopus
# Validate destination connectivity
hooktopus destinations test dst_bq_prod
Want early access? Email cli@hooktopus.io and tell us how you'd use it. We're prioritizing tools we'll actually use ourselves.
Built for engineers
The tool you'd build if you had a Tuesday afternoon.
POST in, BigQuery out. Brutally focused on one job. Read the source code in our public OpenAPI spec — what you see is what we ship.