# Use Hatched with AI coding assistants

> These docs are machine-readable. Point Cursor, Claude Code, Copilot, or any LLM at the right files and drop a ready-made instruction file into your repo.

Source: https://docs.hatched.live/docs/ai-assistants

If you build with an AI coding assistant — Cursor, Claude Code, GitHub Copilot,
Windsurf, Codex, Devin — these docs are designed to feed it cleanly. This page
covers the three things worth wiring up.

## 1. Drop an instruction file into your repo

The single highest-leverage move: give your assistant a short, opinionated
brief on how to use Hatched. We maintain one for you:

```bash
curl -fsSL https://docs.hatched.live/AGENTS.md -o AGENTS.md
```

[View it here](https://docs.hatched.live/AGENTS.md). It works as a standalone
`AGENTS.md` (read by Codex, Cursor, Copilot's coding agent, Devin, Jules, and
more), or paste its contents into `CLAUDE.md`, `.cursor/rules`, or your Copilot
instructions file. It covers:

- installing `@hatched/sdk-js` and initialising the client
- **the cardinal rule** — secret keys (`hatch_live_*`, `hatch_test_*`) are
  server-only; the SDK throws in the browser. Use a widget session token or a
  `hatch_pk_*` publishable key client-side. <AuthBadge kind="api-key" />
- the **first-user bootstrap** — publish a config first, reuse-or-create a buddy
  (never re-create an egg on every load), persist `buddy_id`, mint a widget
  session token; the `snake_case` raw API vs camelCase SDK
- the core flows: `events.send` with a stable `eventId`, `buddies.earn` /
  `spend` / `equip`, gates, webhooks
- verifying webhook signatures against the **raw body** before parsing
- catching typed `HatchedError` subclasses by `.code`
- embedding widgets with the loader script (`data-session-token`) and
  `data-hatched-mount` elements

## 2. Point it at the machine-readable docs

| File | What it is | When to use it |
| --- | --- | --- |
| [`/llms.txt`](https://docs.hatched.live/llms.txt) | A short index of every page — title, one-line summary, URL. Follows the [llms.txt](https://llmstxt.org) convention. | Let the assistant pick which page it needs. |
| [`/llms-full.txt`](https://docs.hatched.live/llms-full.txt) | Every page concatenated into one plain-text document. | Give the assistant the whole docs in a single fetch. |
| `/llm/<path>` | Any single page as raw Markdown — e.g. [`/llm/guides/getting-started`](https://docs.hatched.live/llm/guides/getting-started). | Hand it exactly one page. |

Every docs page also has **Copy as Markdown** and **Open in ChatGPT / Claude**
buttons under the title, so you can ship a page to an assistant in one click.

## 3. Know the rules it must not break

If you take nothing else from this page, make sure your assistant respects
these — they are the mistakes we see most often:

- **Secret keys never leave the server.** Not in a bundle, not in a
  `NEXT_PUBLIC_*` var, not in a mobile app. The SDK enforces this by throwing in
  DOM environments. Browser code gets a [widget session
  token](/docs/concepts/auth-model) (`hatched.widgetSessions.create(...)`) or a
  publishable key.
- **Bootstrap a buddy before minting a widget token.** You can't go from
  `userId` straight to a session token — there's a publish → reuse-or-create egg
  → hatch → `buddy_id` chain, and the assistant must reuse an existing buddy
  rather than create an egg on every render. See [First user bootstrap](/docs/guides/first-user-bootstrap).
- **`events.send` is idempotent on `eventId`.** Always pass a stable, meaningful
  id (`lesson_42:user_7`). Omitting it — or generating a random one on retry —
  double-counts. See [Sending events](/docs/guides/send-events).
- **Verify webhook signatures before parsing.** HMAC over the raw bytes, then
  `JSON.parse`. See [Handling webhooks](/docs/guides/handle-webhooks).
- **Wait on operations, don't poll.** Image-producing calls (hatch, evolve,
  equip) return an `operationId`; use `hatched.operations.wait(operationId)`.
- **Use the SDK, not hand-rolled HTTP.** The [SDK reference](/docs/reference/sdk-js)
  is generated from the package source, so it never drifts.
