---
name: voxie-studio-agent-api
description: Create, inspect, update, and collaborate on voxel scenes through the Voxie Studio Agent API.
---

# Voxie Studio Agent API skill

Use this skill when a user asks you to create or modify voxel art, generate a
Voxie Studio scene, open a generated scene in Studio, manage cloud scenes, or
participate in a live co-create room.

## Canonical references

- API base: `https://api.voxie.studio`
- OpenAPI: `https://api.voxie.studio/v1/openapi.json`
- Agent API docs: `https://voxie.studio/docs/agent-api`
- Ops reference: `https://voxie.studio/docs/ops`
- This skill: `https://voxie.studio/docs/agent-skill.md`

Retrieve the live OpenAPI document when exact endpoint behavior may have
changed. Never invent endpoints or operation names.

## Authentication and secret handling

Agents and scripts authenticate with a Premium API key:

```
Authorization: Bearer vx_live_YOUR_KEY
```

The user creates keys under Voxie Studio Account → Agent API keys.

- Never print, log, commit, or place an API key in a URL.
- Read the key from a secret or environment variable such as
  `VOXIE_API_KEY`.
- Send it only to `https://api.voxie.studio`.
- A returned `readToken` is load-only. It is safe to use only in the returned
  Studio edit URL or a scene GET request; it never grants write access.
- `vx_at_…` browser access tokens are short-lived editor credentials, not
  long-lived agent keys.

## Core workflow

1. Clarify the intended subject, dimensions, palette, and whether the user
   wants a new scene or an update.
2. Prefer declarative `ops` for ordinary construction. Use full
   `ProjectJSON` only when layers, materials, animations, or triggers require
   fields not represented by ops.
3. Keep coordinates integral and the model near the origin.
4. Estimate voxel count before sending large shapes or `voxel.set_many`.
5. Create or patch the scene.
6. Inspect the response and report the `editUrl`, scene ID, and voxel count.
7. If visual correctness matters, fetch the scene and verify key coordinates,
   dimensions, layers, and colors before claiming completion.

## Create a scene

```bash
curl -sS https://api.voxie.studio/v1/scenes \
  -H "Authorization: Bearer $VOXIE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Tiny House",
    "ops": [
      { "op": "color.set", "hex": "#c28569" },
      { "op": "shape.box", "from": [0,0,0], "to": [7,0,7] },
      { "op": "color.set", "hex": "#be4a2f" },
      { "op": "shape.box", "from": [1,1,1], "to": [6,4,6] }
    ]
  }'
```

Success returns HTTP 201 with:

```json
{
  "id": "scene-id",
  "name": "Tiny House",
  "voxelCount": 200,
  "readToken": "load-only-token",
  "editUrl": "https://voxie.studio/studio?agent=…&token=…",
  "apiUrl": "https://api.voxie.studio/v1/scenes/scene-id"
}
```

## Read, update, and delete

```bash
# Read with the owning API key
curl -sS https://api.voxie.studio/v1/scenes/SCENE_ID \
  -H "Authorization: Bearer $VOXIE_API_KEY"

# Replace scene content with newly compiled ops
curl -sS -X PATCH https://api.voxie.studio/v1/scenes/SCENE_ID \
  -H "Authorization: Bearer $VOXIE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"name":"Rebuilt scene","ops":[{"op":"shape.sphere","center":[0,3,0],"radius":3,"hex":"#68d8d8"}]}'

# Append compiled voxels to existing layers
curl -sS -X PATCH https://api.voxie.studio/v1/scenes/SCENE_ID \
  -H "Authorization: Bearer $VOXIE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"append":true,"ops":[{"op":"shape.box","from":[10,0,0],"to":[12,2,2],"hex":"#f8c848"}]}'

# Delete (owner only)
curl -sS -X DELETE https://api.voxie.studio/v1/scenes/SCENE_ID \
  -H "Authorization: Bearer $VOXIE_API_KEY"
```

Important: `PATCH` with `ops` replaces the compiled scene unless
`"append": true` is supplied. Append merges voxels by layer ID and coordinate;
it does not apply every destructive operation to the old scene. For precise
deletion or complex edits, fetch the project, modify it, and PATCH the full
`project`.

## Declarative ops

Coordinates are integer voxel coordinates. Shape endpoints are inclusive.
Color can be `"hex":"#RRGGBB"` or
`"rgba":{"r":0,"g":0,"b":0,"a":255}`.

### Scene and layers

- `{"op":"scene.set_name","name":"Name"}`
- `{"op":"scene.clear"}`
- `{"op":"layer.add","id":"walls","name":"Walls"}`
- `{"op":"layer.set_active","id":"walls"}`
- `{"op":"layer.clear","id":"walls"}`

### Paint state

- `{"op":"color.set","hex":"#ff004d"}`
- `{"op":"mode.set","mode":"add"}`
- Modes: `add`, `sub`, `paint`

### Voxels

- `{"op":"voxel.set","x":0,"y":0,"z":0,"hex":"#ffffff"}`
- `{"op":"voxel.remove","x":0,"y":0,"z":0}`
- `{"op":"voxel.set_many","voxels":[{"x":0,"y":0,"z":0,"hex":"#ffffff"}]}`

### Shapes

- `{"op":"shape.box","from":[0,0,0],"to":[4,4,4],"hex":"#ff004d","mode":"add"}`
- `{"op":"shape.sphere","center":[0,4,0],"radius":3,"hex":"#68d8d8"}`
- `{"op":"shape.cylinder","from":[0,0,0],"to":[0,6,0],"radius":2,"hex":"#f8c848"}`

### Palette

- `{"op":"palette.use","id":"curated_pico8"}`

Do not use undocumented ops. Fetch the live OpenAPI and ops documentation if
you need capabilities beyond this list.

## Modeling guidance

- Treat +Y as up. Use X and Z for the ground plane.
- Start with large forms, then add details.
- Separate semantic parts into named layers when later edits are likely.
- Use boxes for architecture, cylinders for trunks/pillars, spheres for rounded
  masses, and `voxel.set_many` for deliberate detail.
- Avoid accidentally filling enclosed buildings solid. Build floors, walls,
  and roofs as separate thin boxes.
- Use a coherent, limited palette and preserve contrast between adjacent forms.
- For symmetric objects, generate mirrored coordinates programmatically before
  calling `voxel.set_many`.
- Fetch and inspect the final project instead of assuming a successful HTTP
  response means the composition is correct.

## Full ProjectJSON

Send `{"name":"…","project":{…}}` instead of `ops` when needed. A minimal
project contains:

```json
{
  "version": 2,
  "name": "Example",
  "activeLayerId": "main",
  "layers": [{
    "id": "main",
    "name": "Main",
    "visible": true,
    "opacity": 1,
    "locked": false,
    "voxels": [
      {"x":0,"y":0,"z":0,"r":255,"g":255,"b":255,"a":255}
    ]
  }]
}
```

Preserve unknown supported fields when editing a fetched project. Do not
silently discard materials, groups, animations, triggers, or work-area data.

## Cloud scenes and collaboration

- `GET /v1/cloud/scenes` lists owned and shared scenes.
- `POST /v1/cloud/scenes` creates a cloud scene from ProjectJSON; include
  `id` to update an existing scene.
- Creating/hosting requires Premium. Accepted co-creators can edit while the
  owner remains Premium.
- To join live collaboration, POST
  `/v1/rooms/{sceneId}/tickets`, then connect once to the returned `wsUrl`.
- A room starts with `hello.ok` containing the snapshot and sequence.
- Send commits as
  `{"type":"commit","clientOpId":"unique-id","baseSeq":0,"label":"what changed","ops":[…]}`.
- Handle server sequence updates and never blindly retry a commit with a new
  ID after an ambiguous network failure.
- Browser invitees occupy up to four co-creator seats. Agents have a separate
  connection budget and do not consume those seats.

Use plain HTTP create/patch for one-shot generation. Use a room only when the
task requires live, attributed collaboration.

## Limits and error handling

- Maximum project JSON: approximately 5 MB.
- Maximum scene size: approximately 80,000 voxels.
- Co-create: up to four pending + accepted invitees.
- Check HTTP status before parsing success fields.
- 400: malformed body, unsupported project, or project limits exceeded.
- 401: missing/invalid credential or invalid read token.
- 403: Premium required, owner Premium lapsed, or caller lacks write/delete
  permission.
- 404: scene not found or deliberately hidden by access control.
- 409/room errors: refresh state and sequence before deciding whether to retry.
- Respect rate limits and any `Retry-After` header. Use bounded exponential
  backoff only for transient failures.
- Never retry create requests automatically after an ambiguous timeout unless
  duplicate scenes are acceptable.

## Completion checklist

Before reporting success:

- The request used only documented endpoints and ops.
- No credential appears in output, logs, source control, or query strings.
- The response status was successful.
- Scene ID, name, and voxel count were captured.
- The result was fetched and structurally checked when correctness mattered.
- The user received the returned `editUrl` for a newly created scene.
- Any limitation, partial result, or permission failure was stated clearly.
