# Generate a changelog from commits with Pizza Ex Machina's API

Pizza Ex Machina turns a commit list into user-facing release notes with a standing agent: you create it once with changelog instructions on a chosen oven (model), then send each release's commits to its run endpoint. Creating the agent is free, and each run costs a fee of $0.01 per run plus the oven's per-token rates, drawn from prepaid credit. You call `https://api.pizzaexmachina.com` with a `pxm_live_` key, which the agent storefront issues when you buy Credits.

## At a glance

- **Create once:** `POST https://api.pizzaexmachina.com/v1/agents` with `instructions`, `name` and `model`. Creating an agent is free.
- **Run per release:** `POST https://api.pizzaexmachina.com/v1/agents/{agentId}/runs` with `input` set to the commit list.
- **Price per run:** $0.01 per run plus tokens. On `fornetto-1` that is $0.2625 per million tokens for input and $2.10 per million tokens for output.
- **Payment:** prepaid Credits bought on the storefront, with a minimum of $0.50. You send the `pxm_live_` key as `Authorization: Bearer`. Runs are not paid per call.
- **Response:** `output` (text), `model`, a `billed` breakdown and `remainingCreditUsd`.
- **Limits:** run input up to 4,000 characters, instructions up to 4,000 characters, output up to 1,200 tokens per run.
- **Full purchase flow:** [the buyer skill](https://agents.pizzaexmachina.com/zcj/e3h61qy4iwc7/SKILL.md)

## Choose the oven

The oven is fixed when you create the agent. To use a different oven, create a new agent. This guide uses `fornetto-1`; start with the cheapest oven, and keep it if its output passes your own check. A request without `model` creates a `forno-1` agent, so set `model` explicitly. `GET https://api.pizzaexmachina.com/v1/models` returns the current rates for free, with no auth.

## Set up the changelog agent and run it per release

1. Get a key. Buy Credits on the storefront with your buyer bearer, at least $0.50, then redeem a `pxm_live_` key; [the buyer skill](https://agents.pizzaexmachina.com/zcj/e3h61qy4iwc7/SKILL.md) and [Standing accounts](https://agents.pizzaexmachina.com/zcj/e3h61qy4iwc7/accounts.md) cover both. The bearer works only on the storefront, and the key only on the seller API.

2. Create the agent once:

   ```bash
   curl -s -X POST https://api.pizzaexmachina.com/v1/agents \
     -H "Authorization: Bearer $PXM_API_KEY" \
     -H "Content-Type: application/json" \
     -d '{"name": "Changelog Writer", "model": "fornetto-1", "instructions": "Rewrite a list of commit messages as a short changelog for users: group related changes under one heading each, put user-visible changes first, and leave out commit hashes and internal chores."}'
   ```

   The response returns the agent and its run address. This sample response was free and took 0.5 seconds.

   ```json
   {"agent": {"id": "chef_…", "name": "Changelog Writer", "model": "fornetto-1", "tools": [], "createdAt": "…"}, "runUrl": "..."}
   ```

   The run examples below use an agent created with this identical body. Store `agent.id` with your release configuration. `GET https://api.pizzaexmachina.com/v1/agents` lists your agents if you lose it.

3. Send the release's commits as `input`. The instructions travel with the agent, so the run body carries only the commit list:

   ```bash
   curl -s -X POST https://api.pizzaexmachina.com/v1/agents/<agentId>/runs \
     -H "Authorization: Bearer $PXM_API_KEY" \
     -H "Content-Type: application/json" \
     -d '{"input": "feat: export reports as CSV\nfix: login loop after password reset\nchore: bump eslint to 9.2\nfeat: dark mode for the dashboard\nfix: timezone shown as UTC on invoices\nrefactor: split billing service"}'
   ```

   The response itemizes the run in `billed`. The output is abridged here:

   ```json
   {"agent": {"id": "<agentId>", "name": "Changelog Writer"}, "output": "Features\n- Export reports as CSV ...\n- Dark mode for the dashboard ...\n\nBug fixes\n- Fixed login loop after password reset ...\n- Fixed invoices showing timezone as UTC ...", "model": "fornetto-1", "billed": {"runUsd": "...", "inputTokens": 148, "inputTokensUsd": "...", "outputTokens": 436, "outputTokensUsd": "...", "totalUsd": "..."}, "remainingCreditUsd": "..."}
   ```

   This example's `billed` object records the run fee, 148 input tokens and 436 output tokens, for a total of $0.010955 drawn from credit, and the run took 4.7 seconds.

4. Send the next release's commits to the same agent. The instructions are unchanged, and only `input` differs:

   ```bash
   curl -s -X POST https://api.pizzaexmachina.com/v1/agents/<agentId>/runs \
     -H "Authorization: Bearer $PXM_API_KEY" \
     -H "Content-Type: application/json" \
     -d '{"input": "feat: invite teammates by email\nfix: CSV export drops the last row\nperf: cache dashboard queries\nchore: update CI image\nfeat: keyboard shortcut to search"}'
   ```

   The response:

   ```json
   {"agent": {"id": "<agentId>", "name": "Changelog Writer"}, "output": "Added\n- Invite teammates by email.\n- Keyboard shortcut to open search.\n\nImproved\n- Dashboards load faster thanks to cached query results.\n\nFixed\n- CSV export no longer drops the last row.", "model": "fornetto-1", "billed": {"runUsd": "...", "inputTokens": 134, "inputTokensUsd": "...", "outputTokens": 562, "outputTokensUsd": "...", "totalUsd": "..."}, "remainingCreditUsd": "..."}
   ```

   This example's `billed` object records the run fee, 134 input tokens and 562 output tokens, for a total of $0.011215 drawn from credit, and the run took 7.2 seconds. In both examples the output groups changes under plain headings and leaves out the `chore` lines.

5. Write `output` where your release notes go. In CI, build the body with `jq` so newlines are escaped:

   ```bash
   COMMITS="$(git log --no-merges --pretty=format:%s v1.4.0..v1.5.0)"
   jq -n --arg input "$COMMITS" '{input: $input}' \
   | curl -s -X POST "https://api.pizzaexmachina.com/v1/agents/$PXM_AGENT_ID/runs" \
       -H "Authorization: Bearer $PXM_API_KEY" \
       -H "Content-Type: application/json" -d @- > run.json
   jq -r .output run.json > RELEASE_NOTES.md
   ```

## What a run costs

Each run costs the run fee, plus the input tokens times the oven's input rate, plus the output tokens times its output rate. The `billed` object in each response reports the tokens used and the total. On `fornetto-1`, a run with 2,000 input tokens and the 1,200-token output maximum costs $0.013045.

A run is accepted only if your credit covers the run fee. The full cost is drawn after the model answers, so the last run before exhaustion can leave the balance slightly negative. `GET https://api.pizzaexmachina.com/v1/account` shows the remaining credit.

## Long commit lists

The run input takes up to 4,000 characters, and each run returns at most 1,200 output tokens. To handle a longer list:

1. Check the length with `printf '%s' "$COMMITS" | wc -m`.
2. Drop merge commits with `--no-merges`.
3. If the list is still too long, split it at line boundaries into chunks under 4,000 characters.
4. Send each chunk to the same agent and join the outputs.

Each chunk is a separate run with its own fee. There is no batch call.

## Boundaries

- The agent takes text and returns text. It does not read a repository, fetch commits or publish release notes. Your script fetches the commits and writes the output.
- The instructions and oven cannot be changed after creation. To change either, create a new agent and point your script at its id.
- Creating and listing agents is free. Only runs draw credit, and a `502 run_failed` is not billed.

## Errors

| Status and code | Meaning | Action |
| --- | --- | --- |
| `400 invalid_request` | A field is missing or malformed. `detail` names it. | Fix the body. Runs need `input`, and creation needs `instructions`. |
| `401 unauthorized` / `invalid_api_key` | No key, or the key is unknown or revoked | Send the current `pxm_live_` key, or recover it (see the questions below) |
| `402 insufficient_credit` | Credit can't cover the run fee | Top up with `POST https://agents.pizzaexmachina.com/zcj/e3h61qy4iwc7/extend` and an `amountUsd`. The same key keeps working. |
| `502 run_failed` | The model backend could not answer, and no credit is drawn | Retry with backoff |

## Frequently asked questions

### Can I change a changelog agent's instructions or oven later?

No. Both are fixed when the agent is created. To use different instructions or a different oven, create a new agent and send runs to its id.

### Does the agent pull commits from my repository?

No. It takes the commit list as text in `input` and returns the changelog as text in `output`. Your script or CI job gets the commits, for example with `git log`, and writes the result where your release notes go.

### How much does one changelog run cost?

Each run costs the run fee of $0.01 per run plus input and output tokens at the agent's oven rates. Each response's `billed` object reports the exact amount drawn for that run.

### What if my API key is lost?

Redeem a key again from the same account with `POST https://agents.pizzaexmachina.com/zcj/e3h61qy4iwc7/keys/redeem` and your buyer bearer. If the purchase carried a verified email, your human can also sign in at [pizzaexmachina.com](https://pizzaexmachina.com) and generate a new key. A new key revokes the previous one. Buying again is not needed.

### Can I try it without paying?

Yes. A Free trial gives free starting credit, one per human. You claim it with an agent credential whose human has verified an email.

## Keep reading

- [The buyer skill](https://agents.pizzaexmachina.com/zcj/e3h61qy4iwc7/SKILL.md): the full purchase flow
- [Standing accounts](https://agents.pizzaexmachina.com/zcj/e3h61qy4iwc7/accounts.md): key redemption, top-ups and recovery
- [Error reference](https://agents.pizzaexmachina.com/zcj/e3h61qy4iwc7/errors.md): storefront error codes

---

Updated 2026-10-12. All Pizza Ex Machina guides: https://agents.pizzaexmachina.com/guides.md. Storefront: https://agents.pizzaexmachina.com/zcj/e3h61qy4iwc7/llms.txt.
