curl to
show the wire contract. An SDK or any HTTP/1.1 client that can connect to a Unix domain socket can
use the same API.
1. Install the binary
Download the versioned archive and checksum from the Groundhog releases. Published archives target Apple Silicon macOS and x86-64 Linux. Each archive containsgroundhog, BUILD-INFO,
the Groundhog license, and third-party license notices.
For version 0.1.0:
2. Initialize a deployment
groundhog.toml last and is retry-safe:
running the same command again validates the deployment and succeeds without rewriting it.
Conflicting Groundhog-owned files are refused rather than overwritten, while unrelated
siblings in demo/ are preserved.
If DIR is omitted, init uses the current directory:
init for the exact retry and conflict behavior.
3. Review the generated configuration
The generatedgroundhog.toml is local-first:
mode = "open" is the supported security choice. Operations that would extend or attest history
support anchor = "none"; serve, seal, and verify --chain refuse a
signed/mirrored/witnessed requirement instead of silently claiming a weaker guarantee.
An empty token disables HTTP authentication. To require a bearer token, set one in the file and
include it on every request:
4. Start the service
Run this in one terminal:curl is syntactically required by HTTP/1.1 but ignored by
Groundhog, so this guide uses http://ground:
streams array and the genesis warehouse receipt.
Stop the service with Ctrl-C or SIGTERM. Graceful shutdown stops admission, lets enqueued
mutations reach their real storage outcome, and then releases writer ownership.
5. Ingest an atomic event batch
Retry safely
The pair(source, batch_id) is the durable idempotency key. If a request times out or loses its
response, submit the same batch again with the same ID:
- identical content returns
status: "duplicate"and the original event range; - different content under the same ID returns HTTP 409 and writes nothing.
system
and batch IDs beginning with groundhog/ are reserved for Groundhog.
6. Replay durable history
Replay reads the authoritative log directly, so committed events are visible without publishing the warehouse:after, source, stream, kind, and limit; all filters are exact
matches. The response includes two cursor-like fields with different jobs:
last_event_idis the last matching event returned;next_afteris how far the scan progressed, including non-matching events.
next_after when polling a filtered subscription. It lets an empty page advance past
unrelated history. Each response also reports snapshot_through_event_id, the coherent log
frontier captured for that request.
7. Publish the warehouse
Warehouse publication is explicit. Ingest updates the log; it does not automatically refresh SQL relations or the catalog. Leaveserve running and execute:
project captures one coherent log snapshot and atomically publishes a complete warehouse. A
failed publication never displaces the last good generation. The running server adopts a new
generation between requests; an in-flight request
stays pinned to the generation it began with.
This produces two intentionally different freshness paths:
Receipts identify the exact published frontier and make the distinction observable.
8. Query with SQL
events: fixed event columns through the published frontier;meta.streams: source/stream counts, observation times, and kinds; andmeta.projection_state: receipt provenance for the generation.
SELECT or WITH statement over published relations.
File/network access, extensions, mutations, volatile functions, and unsafe engine features are
rejected. A truncated result requires a total top-level ORDER BY; the simplest pattern is to
order by every selected column or use ORDER BY ALL.
Every successful result includes columns, rows, a truncated flag, and a receipt naming
the warehouse frontier, chain head, binary build, storage schema, and projection hash.
9. Discover data through the catalog
10. Verify, seal, and rebuild
Run structural verification:serve and run:
seal requires writer ownership and therefore cannot run while serve owns that writer. It
does not publish the warehouse and does not change logical events, order, IDs, or commitments.
To reconstruct the disposable warehouse from the durable log:
rebuild can run while the service is live. It atomically publishes a replacement and subsequent
requests adopt it without restarting. Repeated rebuilds of the same frontier produce the same
logical relations and receipt; physical DuckDB bytes are not part of that promise.
Common ways to use Groundhog
Record connector output
A connector translates source changes into batches and submits them toPOST /v1/events. Use the
source’s delivery or sync identity as batch_id. Groundhog owns durable ordering,
idempotency, and integrity; the connector retains its source cursor and credentials.
Build a replay consumer
PollGET /v1/events, filter to the relevant source/stream/kind, and persist next_after.
Process business events using immutable event_id values. Each consumer owns its cursor outside
Groundhog, so consumers can move independently over the same history.
Analyze a stable snapshot
Runproject at a chosen operational boundary, use the catalog to discover streams, and send
confined SQL to /v1/query. Retain the returned receipt with reports or agent outputs when you
need to identify exactly which history produced them.
Supervise it from an application
An application can launch a pinnedgroundhog serve child, wait for a successful routed
request over the configured socket, use the public HTTP contract, and stop it with SIGTERM.
This uses the same data directory and compatibility rules as an operator-managed service.
Current binary capabilities
- local Unix socket only; no built-in TCP listener;
opensecurity mode and local anchor modenoneonly;- JSON batch ingest only; no NDJSON stream or server-local path import;
- explicit full warehouse publication; no background or incremental refresh;
- no
current.*state relations or deployment-defined projections; - JSON query results only; and
- no CLI ingest, replay, query, or catalog wrappers. Use the HTTP API or an SDK.