# Publish an Explain figure

> Make an Explain figure in your own coding agent, check it with a dry run, and upload it with an API key or the anyr CLI.


# Publish an Explain figure

[Explain](https://anyrouter.dev/apps/explain) is a collection of interactive isometric figures, each one a real machine that shows how an idea works. You can make a figure in your own coding agent, check it, and upload it.

## Write the figure

Give your agent the prompt at `https://anyrouter.dev/apps/explain/prompt.md`. It describes the format and includes an example. The figure is one JSON object that matches the JSON Schema at `https://anyrouter.dev/apps/explain/schema.json`.

A figure is refused if it breaks one of these rules:

- Build the real machine from at least 12 parts (a few slabs is unfinished work).
- Use the tone hierarchy: a "lo" base and at least one "hi" part for the reader to watch.
- Walk the machine through 3 to 6 steps.
- Each step lights 1 to 4 parts.
- The readout changes from step to step, like a live instrument.
- Every step has its own title.
- Plain text only: no HTML, entities, markdown fences or script URLs.
- No control, zero-width or bidi characters.
- No URLs or domains in the figure's text.
- No placeholder text (TODO, lorem ipsum, Part 1, ...).
- Short lines fit the figure on a phone: hint <= 40, readout <= 32, step title <= 48, part label <= 28 characters.
- Every part is big enough to see (at least 10px a side at the figure's size).
- The figure fits its frame, assembled and pulled apart.

## Check and upload with curl

You need an AnyRouter API key (`sk-ar-v1-...`) from [your dashboard](https://anyrouter.dev/dashboard/keys). Save the request body as `body.json`. It wraps the figure:

```json
{ "payload": { "title": "..." }, "visibility": "unlisted" }
```

Check without saving:

```sh
curl -sS "https://anyrouter.dev/api/v1/apps/explain/submissions?validate_only=1" \
  -H "Authorization: Bearer $ANYROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  --data @body.json
```

A valid figure returns `{"valid": true}`. Then upload it:

```sh
curl -sS "https://anyrouter.dev/api/v1/apps/explain/submissions" \
  -H "Authorization: Bearer $ANYROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  --data @body.json
```

The reply includes the figure's `url`.

## When a figure is refused

A refused figure returns HTTP 422. `error.metadata.issues` lists each problem with where it is, what is wrong and how to fix it:

```json
{
  "error": {
    "metadata": {
      "issues": [
        {
          "path": "steps",
          "code": "step_count",
          "message": "2 steps; use 3 to 6",
          "fix": "Merge or split steps so there are 3 to 6."
        }
      ]
    }
  }
}
```

Fix each issue and check again.

## Use the anyr CLI

The file holds the figure itself, not the wrapper.

```sh
anyr publish explain figure.json --dry-run
anyr publish explain figure.json
```

## Visibility and review

`visibility` is `private`, `unlisted` (the default) or `public`. A private figure is only visible to you, an unlisted figure is visible to anyone with its link, and a public figure joins the Collection after review.


## Related

- [Errors](/docs/guides/errors.md)
- [AnyRouter CLI](/docs/cli.md)
