OpenHunt Docs

API & sync

The deliberately small REST API — sessions, offline-first sync, and sharing — with OpenAPI built in.

The API is small on purpose, and stays that way: anything that can be a static artifact published by the pipeline must be one, so the server's job reduces to what genuinely needs a database — accounts, sync, and sharing. It's one Rust binary (axum) against Postgres.

Map tiles are never served by the API.

  • Base path: /v1
  • Spec: the server publishes OpenAPI at /v1/openapi.json
  • Health: GET /healthz
  • Auth: session cookie (web) or the same session token as a bearer header (mobile). Cookie-authenticated writes are origin-checked against ALLOWED_ORIGINS.

Endpoints

Method & pathWhat it does
POST /v1/auth/registerCreate an account.
POST /v1/auth/loginStart a session.
POST /v1/auth/logoutEnd it.
POST /v1/auth/request-verify · POST /v1/auth/verifyEmail verification.
POST /v1/auth/request-password-reset · POST /v1/auth/reset-passwordPassword reset.
GET·PATCH·DELETE /v1/meThe signed-in user: profile, settings, entitlements — and account deletion.
GET /v1/sessions · DELETE /v1/sessions/{id}List and revoke device sessions.
GET·POST /v1/shares · GET·DELETE /v1/shares/{token}Create, resolve, and revoke share links.
GET·POST /v1/syncPull and push for the sync protocol below.

The sync protocol

Clients are local-first: the device store (IndexedDB on web, SQLite on mobile) is authoritative in the field, and the server reconciles.

  • Client-generated IDs. Objects get UUIDv7 ids on the device, so creating a waypoint never waits on the network.
  • Push sends an outbox of changed objects as versioned envelopes; an Idempotency-Key header makes retries safe on a flaky connection.
  • Pull streams changes since a cursor; the client applies them and advances the cursor.
  • Conflict resolution is per-object last-write-wins. Waypoints and routes are coarse objects edited by one hunter at a time in practice; deletes travel as tombstones.

The same protocol serves web and mobile from one implementation — the mobile sync client is a line-for-line port of the web's.

Entitlements

Plans flow through one seam: the session's entitlements object, read from /v1/me. Clients never scatter plan checks — they read what the server says this account can do. Self-hosted deployments run ungated.

Errors and versioning

Breaking a payload schema requires a version bump and a migration note, even pre-1.0. The OpenAPI spec at /v1/openapi.json is the contract — the web client's typed API layer is generated from it.

On this page