HTTP API
Lean API contract and state machines — V1 scope, endpoints, authentication, and the business processes behind each operation.
Goal: Position Hatched as a narrow-scope product that does one thing exceptionally well, rather than an "enterprise does-everything" platform.
This document clarifies three things:
- Which business processes V1 definitively supports
- Which state machines make the system deterministic
- How the API contracts stay lean and easy to integrate
1. Product Philosophy
V1 targets for Hatched:
- Not a "platform" where the customer designs their own game
- A service that reliably produces buddy progression from the customer's existing product events
That's why V1 follows these principles:
- Template-first: limited rule types instead of a free-form rule language
- Publish-before-live: progression config changes are edited in draft, then published
- Async-by-default: visual-producing jobs are tracked via operations
- Read vs write separation: easy for widgets to read, tighter controls on mutations
- Canonical state lives in Hatched: customers may keep a local copy, but Hatched is the source of truth
2. V1 Scope
2.1 Definitely in V1
- Preset plan selection and customization
- Skill set definition
- Coin rules
- Badge rules
- Evolution readiness and evolution trigger
- Item marketplace
- Buddy widget
- Marketplace widget
- Event ingestion
- Webhook delivery
- Multi-buddy support
2.2 Not in V1
- Full no-code workflow builder
- Unlimited rule engine with if/else trees
- Cross-customer shared economy
- Buddy-to-buddy social graph
- Full user-level CRM
- Real-time multiplayer / competition engine
- Arbitrary CSS/JS execution on the customer side
- Custom approval flows tailored per customer need
2.3 Deliberately limited in V1
- Rule types are picked from fixed enums
- Widget theme is configurable but not an infinite design surface
- Evolution capped at 5 stages
- Token types start with a limited set of system tokens
- Marketplace visibility and requirement logic ships with predefined operators
3. User-Friendly Business Processes
3.1 Customer onboarding
Goal: ship an integration that's live in 10 minutes.
Flow:
- Customer creates an account
- Picks a preset plan
- Lightly edits skill, badge, coin and evolution fields
- Publishes the draft
- Receives an API key
- Sends the first
POST /eventsrequest - Generates a widget token and embeds it
UI principles:
- First screen exposes at most 3 major decisions: preset, style, widget theme
- "Advanced" fields are collapsed by default in every editor
- No "empty page" feeling; the starter config from the preset is always visible
3.2 Progression config change
Goal: make changes without disturbing existing users' balance.
Flow:
- Customer opens the draft config
- Edits skill/badge/coin/evolution fields
- System shows an impact summary:
- affects new buddies
- does not affect existing buddies
- migration can be run separately on demand
- Customer publishes
- New
config_versionbecomes active
UI principles:
- "Save" and "Publish" separation must be obvious
- Publish modal uses impact language, not technical jargon
- "This change does not retroactively affect existing buddies" must be clearly shown
3.3 Event-driven reward generation
Goal: the customer only sends the event; Hatched computes the reward.
Flow:
- Customer sends the event via
POST /events - Hatched deduplicates the event
- Rule engine computes effects
- Writes coin/token/badge/streak/evolution_ready effects
- Emits a webhook if needed
UI principles:
- Dashboard shows "recent events" and "generated effects" side by side
- Debug screen gives a clear answer to "why didn't this event produce a reward?"
3.4 Hatch / equip / evolve
Goal: make visual-producing flows deterministic and understandable.
Flow:
- Customer or widget initiates an action
- API returns an
operation_id - Worker finishes the job
- Result arrives via webhook or polling
UI principles:
- "Processing..." is a first-class state
- Error messages are action-specific, not generic "Image generation failed"
- The user must not retry the same action in a panic
3.5 Widget access
Goal: easy to integrate, but controlled on the write side.
Modes:
- Read-only embed: buddy widget, leaderboard
- Interactive session: marketplace purchase, equip item
UI principles:
- Embed snippet must be short
- Token generation should feel like a "copy-paste snippet" experience
- A read-only embed should require the minimum possible backend integration
4. Canonical Domain Concepts
4.1 Customer
The B2B tenant that uses Hatched.
Owns:
- plan
- settings
- active_config_version_id
4.2 ConfigVersion
Immutable snapshot of progression logic.
Contains:
- skill set
- coin rules
- badge definitions
- evolution rules
- token rules
- marketplace requirements
4.3 Egg
The pending object before a buddy is born.
Rules:
- bound to a specific user
- created with a config_version
- transitions to a closed state once hatched
4.4 Buddy
A user-owned progression unit.
Rules:
- a user can own multiple buddies
- a buddy is pinned to a single config_version
- its version does not change unless migration happens
4.5 EventIngestion
The recorded external domain event from a customer.
Rules:
customer_id + event_idis unique- the same event does not produce a reward twice
4.6 EconomyLedger
Immutable ledger of coin/token mutations.
Rules:
- each row is a credit or a debit
- balance is a computed/projection field
- mutation endpoints write to the ledger
4.7 Operation
Record for tracking an asynchronous job.
Types:
- hatch
- equip_item
- evolve
5. State Machines
5.1 ConfigVersion State Machine
States:
draftpublishedarchived
Transitions:
draft -> publishedpublished -> archived
Rules:
- only one
publishedversion may be active - publish creates a new version; it never mutates an existing one
5.2 Egg State Machine
States:
waitingreadyhatchinghatchedcancelled
Transitions:
waiting -> readyready -> hatchinghatching -> hatchedwaiting -> cancelledready -> cancelled
Rules:
hatchmay only be initiated fromreadyhatchingpersists until the operation completes
5.3 Buddy State Machine
The top-level buddy state is kept simple:
activearchived
A buddy's real variables are:
evolution_stageskillscoinstokensequipped_items
Rules:
- an attribute-based model is preferred over a progression state machine
- this keeps the UI simpler
5.4 Operation State Machine
States:
pendingprocessingcompletedfailedcancelled
Transitions:
pending -> processingprocessing -> completedprocessing -> failedpending -> cancelled
Rules:
- the client never treats the result as final until it sees
completed/failed
5.5 WidgetSession State Machine
States:
issuedactiveexpiredrevoked
Rules:
- read-only tokens may be longer-lived
- interactive tokens must be short-lived
- interactive tokens operate on scopes
6. Lean API Contract
6.1 Public integration endpoints
POST /api/v1/eggs
Purpose:
- create a pending egg record for a user
Request:
{
"user_id": "user_123",
"metadata": {
"age": 12,
"level": "beginner"
}
}Response:
{
"egg_id": "egg_abc",
"status": "waiting",
"visual_variant": 7,
"config_version_id": "cfg_v12"
}PATCH /api/v1/eggs/{egg_id}/status
Purpose:
- mark the egg
readyor cancel it
Allowed statuses:
readycancelled
POST /api/v1/eggs/{egg_id}/hatch
Purpose:
- kick off an async hatch operation
Response:
{
"accepted": true,
"operation_id": "op_123",
"status": "pending"
}POST /api/v1/events
Purpose:
- ingest a customer domain event
Request:
{
"event_id": "evt_789",
"user_id": "user_123",
"type": "lesson_completed",
"occurred_at": "2026-04-08T10:30:00Z",
"properties": {
"lesson_id": "lesson_456",
"score": 87
}
}Response:
{
"accepted": true,
"event_id": "evt_789",
"effects": {
"coins": 10,
"badges_awarded": [],
"tokens": [],
"evolution_ready": false
}
}GET /api/v1/buddies/{buddy_id}
Purpose:
- return canonical buddy state
POST /api/v1/buddies/{buddy_id}/evolve
Purpose:
- start an async evolution operation
PATCH /api/v1/buddies/{buddy_id}/equipped-items
Purpose:
- start an equip/unequip operation
GET /api/v1/operations/{operation_id}
Purpose:
- read the status of a hatch/equip/evolve
6.2 Manual override endpoints
These endpoints ship in V1 but are not marketed as the "primary flow":
PATCH /buddies/{id}/skillsPOST /buddies/{id}/coinsPOST /buddies/{id}/coins/spendPOST /buddies/{id}/badgesPOST /buddies/{id}/tokens
Use cases:
- admin correction
- migration
- special campaign
- support operation
6.3 Widget endpoints
POST /api/v1/widget-sessions
Purpose:
- mint an interactive widget session token
Request:
{
"buddy_id": "bdy_abc123",
"scopes": ["marketplace:purchase", "items:equip"]
}Response:
{
"token": "wgt_sess_xxx",
"expires_at": "2026-04-08T11:00:00Z"
}POST /api/v1/embed-tokens
Purpose:
- mint a signed token for a read-only widget
7. UX Guardrails for the Dashboard
7.1 Rule templates instead of a rule builder
The V1 panel must offer:
- Pick a trigger
- Pick a reward
- Pick a limit
- Preview impact
The V1 panel must NOT offer:
- nested if/else
- custom expression language
- event transformation DSL
- arbitrary JSON editor as the primary UX
7.2 Publish UX
Every progression editor follows this shape:
- Draft badge
- Unsaved changes indicator
- Publish CTA
- Impact summary
- "Publish a new version" instead of a rollback model
7.3 Support UX
Support/operator screens must surface:
- recent events
- effects generated from an event
- operation status
- the user's buddy list
- recent ledger activity
These screens exist for operational confidence, not enterprise complexity.
8. Business Process Decisions
8.1 What we keep centralized
Hatched owns the truth for:
- progression truth
- config version truth
- buddy ownership truth
- operation truth
- ledger truth
8.2 What we leave to the customer
The customer owns:
- event production
- user identity mapping
- when a product action emits an event
- maintaining the buddy ID list inside their own product UI
- which widget appears on which screen
8.3 What we deliberately don't build
- We do not move the customer's whole business logic into Hatched
- We are not a full BPM/workflow product
- We are not a CRM or engagement automation hub
- We do not build an infinitely configurable admin panel
9. Recommended V1 Motto
"Customer events in, progression out."
That's the strongest, simplest positioning for the product:
- The customer emits events
- Hatched computes progression
- The widget renders the result
Everything else is secondary.
Endpoints
The API has no route files yet. Once routes exist under apps/api/src/routes, this section auto-populates.