Buddy & hatch
The avatar at the heart of Hatched — how it's created, what hatch means, and how it grows.
A buddy is the persistent companion a user gets when they join your Hatched programme. Everything else — skills, coins, streaks, badges — hangs off the buddy.
Egg and hatch
Before a buddy exists, there is an egg. Creating an egg is the first write you make to the Hatched API:
const egg = await hatched.eggs.create({
userId: 'user_42',
});The egg is pinned to the current config version
on the customer (set during onboarding via apply-preset, or via the
Dashboard) and carries any audience tags you passed. It doesn't render a
visible buddy yet — it's a placeholder with pending image generation.
Move the egg from waiting to ready once your own onboarding gate is
complete; only ready eggs can hatch.
Hatch is the ceremony that turns an egg into a buddy:
await hatched.eggs.updateStatus(egg.eggId, 'ready');
const op = await hatched.eggs.hatch(egg.eggId);
const buddy = await hatched.operations.wait(op.operationId);Hatching is asynchronous because image generation takes 5–20 seconds. You
get an operation id back; poll it with operations.wait or listen for the
buddy.hatched webhook.
One user, possibly several buddies
By default there is one buddy per (customer, external_user_id) pair. When audiences are in play, a single user can have one buddy per audience — useful when the same person plays two roles (student and teacher, for instance).
What a buddy carries
A buddy is not just a picture. It holds:
- a config_version_id — which rulebook it lives under
- a skills map — each skill with value and level
- coins and any token balances
- a list of awarded badges
- a set of streak counters
- an evolution stage, current
image_url, and barebase_image_url - equipped marketplace items
- a progression summary for XP, badges, items, and streak counters
- an appearance block for pending or failed item compositing
- an audience tag (if configured)
The widget reads this shape directly; your backend can mirror it via webhooks if you need your own source of truth for UX.
Appearance state
buddy.appearance separates the desired outfit from the image that is
currently safe to display:
ready—image_urlincludes the rendered equipped items.pending— a new composite is being generated.awaiting_credits— the composite will retry after image credits are available.failed— the render needs operator action or a retry.
Use desired_equipped_item_ids to know what the user wants equipped and
rendered_equipped_item_ids to know what is visible in image_url. If a
failed appearance has error.code === 'needs_rerender', regenerate the bare
stage with buddies.rerenderAppearance(buddyId), wait for ready, then
re-equip the items.
Lifecycle
Buddies are long-lived. They don't expire on their own — they evolve. When you update the rule set, existing buddies stay pinned to their old config version; you migrate them explicitly when you're ready.
Related
- Evolution — how the buddy changes over time.
- Compositing & stages — the full
appearancestate machine. - Config versions — the rulebook a buddy is pinned to.
- Getting started — create and hatch your first buddy.