Hogsend
Operating

Admin Guide

Operating your Hogsend instance — contacts, journeys, email delivery, and monitoring

This guide is for operators — the people keeping Hogsend running, managing contacts, debugging journeys, and maintaining email deliverability. If you're writing journey code, start with the Journeys page. If you need raw endpoint definitions, see the API Reference.

There are two front-ends over the admin plane: the human Studio UI (Better Auth login — public sign-up is disabled, so the first admin is minted from your server; see Authentication) and machine API keys for the CLI, CI, and your own code.

What the Admin API Gives You

The admin API (/v1/admin/*) is the operations control plane for your Hogsend instance. Through it you can:

  • Manage contacts -- create, update, search, import/export, and view full activity timelines
  • Operate journeys -- enable/disable without redeploying, inspect running instances, cancel stuck runs, manually enroll users
  • Track email delivery -- browse send history, inspect delivery timelines, resend failed emails, monitor deliverability trends
  • Monitor system health -- check component status, review real-time metrics, track event volume
  • Set up alerts -- define threshold-based rules that notify you via Slack, webhook, or email when things go wrong
  • Audit everything -- every admin mutation is automatically logged with actor, action, resource, and IP address

Architecture at a Glance

Your scaffolded app runs as two processes from the same codebase — an API process and a worker process, both wiring your content into the @hogsend/engine factories:

                      +-------------------+
  HTTP requests  ---> |    API Process    | ---> Database (TimescaleDB)
                      |  (Hono on :3002)  | ---> Redis (caching)
                      +-------------------+
                             |
                     events pushed to
                             |
                             v
                      +-------------------+
                      |  Hatchet Engine   | <--- task orchestration
                      +-------------------+
                             |
                      +-------------------+
                      |  Worker Process   | ---> Email provider (Resend by default)
                      |  (Hatchet tasks)  | ---> PostHog (event capture)
                      +-------------------+
  • The API process handles HTTP requests, authenticates admin keys, processes event ingestion, and pushes tasks to Hatchet.
  • The Worker process executes durable tasks -- journey runs, email sends, bulk imports. It picks up work from the Hatchet queue and runs it reliably. Email goes out through a swappable provider (Resend by default).
  • Hatchet is the task orchestration engine that routes events to matching journeys, manages retries, and provides durable execution guarantees.
  • TimescaleDB stores contacts, events, journey states, email records, audit logs, and all other persistent data.
  • Redis is used for Better Auth sessions, password-reset tokens, rate limiting, and PostHog property caching — it is required in production.

Both processes share the same database, so admin API queries always reflect the latest state.

Getting Started

1. Get an API key

If you have the ADMIN_API_KEY environment variable set, you can use that immediately:

curl -H "Authorization: Bearer $ADMIN_API_KEY" \
  http://localhost:3002/v1/health

For production, create a scoped database-backed key (see Authentication):

curl -X POST http://localhost:3002/v1/admin/api-keys \
  -H "Authorization: Bearer $ADMIN_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Ops Dashboard", "scopes": ["read"] }'

2. Check system health

curl -H "Authorization: Bearer your-api-key" \
  http://localhost:3002/v1/health

A healthy response looks like:

{
  "status": "healthy",
  "uptime": 12345.678,
  "timestamp": "2026-05-25T10:30:00.000Z",
  "version": "0.0.1",
  "components": {
    "database": { "status": "up", "latencyMs": 1 },
    "redis": { "status": "up" }
  },
  "schema": {
    "engine": { "required": "0012", "applied": "0012", "inSync": true, "pending": [] },
    "client": { "required": null, "applied": null, "inSync": true, "pending": [] }
  }
}

The schema block reports the two migration tracks. status is migration_pending when either is behind. See Monitoring.

3. View your journeys

curl -H "Authorization: Bearer your-api-key" \
  http://localhost:3002/v1/admin/journeys

4. Check the overview metrics

curl -H "Authorization: Bearer your-api-key" \
  http://localhost:3002/v1/admin/metrics/overview

Endpoint Quick Reference

All endpoints are prefixed with /v1/admin unless noted. Authentication is via Authorization: Bearer <api-key>.

Health & Metrics

EndpointMethodScopeDescription
/v1/healthGETNoneComponent health status
/metrics/overviewGETreadSystem-wide summary
/metrics/journeysGETreadPer-journey performance
/metrics/journeys/{id}GETreadSingle journey funnel
/metrics/emailsGETreadPer-template email stats
/metrics/emails/deliverabilityGETreadDeliverability trends
/metrics/eventsGETreadEvent volume by name/time

Contacts

EndpointMethodScopeDescription
/contactsGETreadList and search contacts
/contacts/{id}GETreadGet contact with preferences
/contactsPOSTfull-adminCreate a contact
/contacts/{id}PATCHfull-adminUpdate a contact
/contacts/{id}DELETEfull-adminSoft-delete a contact
/contacts/{id}/preferencesGETreadGet email preferences
/contacts/{id}/preferencesPUTfull-adminUpdate email preferences
/contacts/{id}/timelineGETreadFull activity timeline
/contacts/importPOSTfull-adminBulk import (CSV/JSON)
/contacts/import/{jobId}GETreadCheck import status
/contacts/exportGETreadExport contacts

Journeys

EndpointMethodScopeDescription
/journeysGETreadList journeys with counts
/journeys/{id}GETreadJourney detail + recent states
/journeys/{id}PATCHjourney-adminEnable/disable a journey
/journeys/{id}/statesGETreadList journey instances
/journeys/{id}/states/{stateId}GETreadInstance detail + logs
/journeys/{id}/states/{stateId}DELETEjourney-adminCancel a running instance
/journeys/{id}/enrollPOSTjourney-adminEnroll a single user
/journeys/{id}/enroll/batchPOSTjourney-adminBatch enroll (max 500)

Emails

EndpointMethodScopeDescription
/emailsGETreadList email sends
/emails/{id}GETreadEmail detail + tracked links
/emails/{id}/resendPOSTfull-adminRetry a failed email

Events

EndpointMethodScopeDescription
/eventsGETreadList events
/events/{id}GETreadEvent detail
/events/replayPOSTfull-adminReplay events

API Keys

EndpointMethodScopeDescription
/api-keysGETfull-adminList keys
/api-keysPOSTfull-adminCreate a key
/api-keys/{id}DELETEfull-adminRevoke a key

Alerts & Monitoring

EndpointMethodScopeDescription
/alerts/rulesGETreadList alert rules
/alerts/rulesPOSTfull-adminCreate a rule
/alerts/rules/{id}PATCHfull-adminUpdate a rule
/alerts/rules/{id}DELETEfull-adminDelete a rule
/alerts/historyGETreadPast alert triggers
/dlqGETreadDead letter queue
/dlq/{id}/retryPOSTfull-adminRetry a DLQ entry
/dlq/{id}DELETEfull-adminDiscard a DLQ entry
/audit-logsGETreadAudit trail
/journey-logs/{stateId}GETreadJourney execution logs

Next Steps

On this page