{
  "openapi": "3.1.0",
  "info": {
    "title": "ResourcePack AI API",
    "version": "1.0.0",
    "description": "Create packs, generate blocks, models, items, GUIs, icons and sounds into them, and download the result.\n\nEvery generation is asynchronous: the endpoint answers 202 with a job handle and you poll it. Calls spend the same AI Credits the app does."
  },
  "servers": [
    {
      "url": "https://api.resourcepack.ai/v1"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "Your API key, from the account page. Send it as `Authorization: Bearer rpai_…`."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "description": "Every failure from this API has this shape.",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable and machine-readable. Branch on this, never on `message`."
              },
              "message": {
                "type": "string",
                "description": "Human-readable. The wording may change; the code may not."
              }
            },
            "required": [
              "code",
              "message"
            ]
          }
        },
        "required": [
          "error"
        ]
      }
    }
  },
  "x-error-codes": {
    "invalid_request": {
      "status": 400,
      "description": "Something in the body or query is wrong. `message` says what."
    },
    "invalid_json": {
      "status": 400,
      "description": "The request body wasn't a JSON object."
    },
    "invalid_job_handle": {
      "status": 400,
      "description": "A job handle that isn't `<pack>:<kind>:<name>`."
    },
    "missing_api_key": {
      "status": 401,
      "description": "No `Authorization: Bearer` header was sent."
    },
    "invalid_api_key": {
      "status": 401,
      "description": "The key isn't one of ours, or it has been revoked."
    },
    "insufficient_credits": {
      "status": 402,
      "description": "Not enough AI Credits to run this. Nothing was started or charged."
    },
    "plan_required": {
      "status": 403,
      "description": "The key is valid, but its account is on Starter. The API needs a paid plan."
    },
    "forbidden": {
      "status": 403,
      "description": "Valid key, but not permitted to do this in this pack."
    },
    "pack_limit_reached": {
      "status": 403,
      "description": "The account is at its plan's pack limit."
    },
    "asset_limit_reached": {
      "status": 403,
      "description": "The pack is at its asset limit."
    },
    "not_found": {
      "status": 404,
      "description": "No such pack, asset or job."
    },
    "job_not_found": {
      "status": 404,
      "description": "No job by that handle."
    },
    "conflict": {
      "status": 409,
      "description": "That vanilla target is already reskinned in this pack. Change it in the Studio rather than overwriting it."
    },
    "still_generating": {
      "status": 409,
      "description": "The asset exists but isn't finished. Poll its job until it's ready."
    },
    "generation_failed": {
      "status": 409,
      "description": "That asset's generation failed. Its job carries the reason."
    },
    "rate_limited": {
      "status": 429,
      "description": "Too many requests. `message` says how long to wait; see Rate limits."
    },
    "unavailable": {
      "status": 503,
      "description": "The feature behind this endpoint is switched off."
    },
    "export_failed": {
      "status": 500,
      "description": "The zip couldn't be built."
    },
    "request_failed": {
      "status": 500,
      "description": "Something went wrong that doesn't have a more specific code."
    }
  },
  "tags": [
    {
      "name": "Packs",
      "description": "Create packs and read what's in them."
    },
    {
      "name": "Generating",
      "description": "The six generation endpoints."
    },
    {
      "name": "Jobs",
      "description": "Follow a generation to completion."
    }
  ],
  "paths": {
    "/packs": {
      "get": {
        "operationId": "listPacks",
        "summary": "List packs",
        "description": "Every pack this key can reach — packs you own and packs somebody added you to, in one list with a `role` on each.",
        "tags": [
          "Packs"
        ],
        "responses": {
          "200": {
            "description": "The packs this key can reach.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "packs": {
                      "type": "array",
                      "description": "Owned and shared packs together, told apart by `role`.",
                      "items": {
                        "type": "object",
                        "description": "One pack.",
                        "properties": {
                          "slug": {
                            "type": "string",
                            "description": "The pack's id. Every other path takes this."
                          },
                          "name": {
                            "type": "string",
                            "description": "Its display name."
                          },
                          "minecraftVersion": {
                            "type": "string",
                            "description": "The version the pack is authored against."
                          },
                          "role": {
                            "type": "string",
                            "description": "Whether this key's owner owns the pack or was added to it.",
                            "enum": [
                              "owner",
                              "collaborator"
                            ]
                          },
                          "createdAt": {
                            "type": "string",
                            "description": "ISO 8601."
                          },
                          "updatedAt": {
                            "type": "string",
                            "description": "ISO 8601."
                          },
                          "assetCounts": {
                            "type": "object",
                            "description": "How much the pack holds, by kind.",
                            "properties": {
                              "textures": {
                                "type": "integer",
                                "description": "Block textures, item sprites and GUI sheets."
                              },
                              "models": {
                                "type": "integer",
                                "description": "3D models."
                              },
                              "icons": {
                                "type": "integer",
                                "description": "Font glyphs."
                              },
                              "sounds": {
                                "type": "integer",
                                "description": "Sound events."
                              }
                            },
                            "required": [
                              "textures",
                              "models",
                              "icons",
                              "sounds"
                            ]
                          }
                        },
                        "required": [
                          "slug",
                          "name",
                          "minecraftVersion",
                          "role",
                          "createdAt",
                          "updatedAt",
                          "assetCounts"
                        ]
                      }
                    }
                  },
                  "required": [
                    "packs"
                  ]
                },
                "example": {
                  "packs": [
                    {
                      "slug": "medieval-keep",
                      "name": "Medieval Keep",
                      "minecraftVersion": "1.20.1",
                      "role": "owner",
                      "createdAt": "2026-08-01T09:12:44.000Z",
                      "updatedAt": "2026-08-10T16:02:11.000Z",
                      "assetCounts": {
                        "textures": 42,
                        "models": 7,
                        "icons": 3,
                        "sounds": 1
                      }
                    }
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error. Possible `error.code` values: `missing_api_key`, `invalid_api_key`, `plan_required`, `not_found`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Every failure from this API has this shape.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable and machine-readable. Branch on this, never on `message`."
                        },
                        "message": {
                          "type": "string",
                          "description": "Human-readable. The wording may change; the code may not."
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createPack",
        "summary": "Create a pack",
        "description": "The slug is derived from the name and made unique — read it from the response rather than predicting it, because a second pack of the same name doesn't get the slug you'd guess.\n\nJSON only. The Studio's own create dialog is multipart because it also accepts an icon image, which has no business being the shape of the API's simplest call.",
        "tags": [
          "Packs"
        ],
        "responses": {
          "201": {
            "description": "Created.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "pack": {
                      "type": "object",
                      "description": "The new pack.",
                      "properties": {
                        "slug": {
                          "type": "string",
                          "description": "The pack's id. Every other path takes this."
                        },
                        "name": {
                          "type": "string",
                          "description": "Its display name."
                        },
                        "minecraftVersion": {
                          "type": "string",
                          "description": "The version the pack is authored against."
                        },
                        "role": {
                          "type": "string",
                          "description": "Whether this key's owner owns the pack or was added to it.",
                          "enum": [
                            "owner",
                            "collaborator"
                          ]
                        },
                        "createdAt": {
                          "type": "string",
                          "description": "ISO 8601."
                        },
                        "updatedAt": {
                          "type": "string",
                          "description": "ISO 8601."
                        },
                        "assetCounts": {
                          "type": "object",
                          "description": "How much the pack holds, by kind.",
                          "properties": {
                            "textures": {
                              "type": "integer",
                              "description": "Block textures, item sprites and GUI sheets."
                            },
                            "models": {
                              "type": "integer",
                              "description": "3D models."
                            },
                            "icons": {
                              "type": "integer",
                              "description": "Font glyphs."
                            },
                            "sounds": {
                              "type": "integer",
                              "description": "Sound events."
                            }
                          },
                          "required": [
                            "textures",
                            "models",
                            "icons",
                            "sounds"
                          ]
                        }
                      },
                      "required": [
                        "slug",
                        "name",
                        "minecraftVersion",
                        "role",
                        "createdAt",
                        "updatedAt",
                        "assetCounts"
                      ]
                    }
                  },
                  "required": [
                    "pack"
                  ]
                },
                "example": {
                  "pack": {
                    "slug": "medieval-keep",
                    "name": "Medieval Keep",
                    "role": "owner"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error. Possible `error.code` values: `missing_api_key`, `invalid_api_key`, `plan_required`, `not_found`, `invalid_request`, `pack_limit_reached`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Every failure from this API has this shape.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable and machine-readable. Branch on this, never on `message`."
                        },
                        "message": {
                          "type": "string",
                          "description": "Human-readable. The wording may change; the code may not."
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "The pack's display name.",
                    "maxLength": 100,
                    "example": "Medieval Keep"
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        }
      }
    },
    "/packs/{pack}": {
      "get": {
        "operationId": "getPack",
        "summary": "Get a pack",
        "description": "The same object as the listing, plus `minVersion` — the oldest Minecraft version this pack's contents will actually load on, derived from what's in it rather than from what the pack is nominally set to.",
        "tags": [
          "Packs"
        ],
        "responses": {
          "200": {
            "description": "The pack.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "pack": {
                      "type": "object",
                      "description": "The pack, plus the version floor its contents imply.",
                      "properties": {
                        "slug": {
                          "type": "string",
                          "description": "The pack's id. Every other path takes this."
                        },
                        "name": {
                          "type": "string",
                          "description": "Its display name."
                        },
                        "minecraftVersion": {
                          "type": "string",
                          "description": "The version the pack is authored against."
                        },
                        "role": {
                          "type": "string",
                          "description": "Whether this key's owner owns the pack or was added to it.",
                          "enum": [
                            "owner",
                            "collaborator"
                          ]
                        },
                        "createdAt": {
                          "type": "string",
                          "description": "ISO 8601."
                        },
                        "updatedAt": {
                          "type": "string",
                          "description": "ISO 8601."
                        },
                        "assetCounts": {
                          "type": "object",
                          "description": "How much the pack holds, by kind.",
                          "properties": {
                            "textures": {
                              "type": "integer",
                              "description": "Block textures, item sprites and GUI sheets."
                            },
                            "models": {
                              "type": "integer",
                              "description": "3D models."
                            },
                            "icons": {
                              "type": "integer",
                              "description": "Font glyphs."
                            },
                            "sounds": {
                              "type": "integer",
                              "description": "Sound events."
                            }
                          },
                          "required": [
                            "textures",
                            "models",
                            "icons",
                            "sounds"
                          ]
                        },
                        "minVersion": {
                          "type": "string",
                          "description": "Oldest Minecraft version this pack's contents will load on."
                        }
                      },
                      "required": [
                        "slug",
                        "name",
                        "minecraftVersion",
                        "role",
                        "createdAt",
                        "updatedAt",
                        "assetCounts",
                        "minVersion"
                      ]
                    }
                  },
                  "required": [
                    "pack"
                  ]
                },
                "example": {
                  "pack": {
                    "slug": "medieval-keep",
                    "minVersion": "1.21.4"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error. Possible `error.code` values: `missing_api_key`, `invalid_api_key`, `plan_required`, `not_found`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Every failure from this API has this shape.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable and machine-readable. Branch on this, never on `message`."
                        },
                        "message": {
                          "type": "string",
                          "description": "Human-readable. The wording may change; the code may not."
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "pack",
            "in": "path",
            "required": true,
            "description": "The pack's slug, as returned by the packs endpoints.",
            "schema": {
              "type": "string",
              "description": "The pack's slug, as returned by the packs endpoints.",
              "example": "medieval-keep"
            }
          }
        ]
      }
    },
    "/packs/{pack}/assets": {
      "get": {
        "operationId": "listAssets",
        "summary": "List a pack's assets",
        "description": "Page until `nextCursor` is null. An asset's `id` is also its job handle, so this is how you find the handle for something generated in an earlier run.\n\nNote the four storage kinds don't map one-to-one onto the six things you can generate: item sprites and GUI sheets are both stored as `texture` under a prefixed name (`item:sword`, `gui:shop_menu`, `hud:frostbite`), icons are stored as `font`, and a 3D item is a `model`.",
        "tags": [
          "Packs"
        ],
        "responses": {
          "200": {
            "description": "One page of assets.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "assets": {
                      "type": "array",
                      "description": "This page of assets.",
                      "items": {
                        "type": "object",
                        "description": "One asset.",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "Stable id, and the job handle this asset was created under."
                          },
                          "kind": {
                            "type": "string",
                            "description": "Which store it lives in.",
                            "enum": [
                              "texture",
                              "model",
                              "font",
                              "sound"
                            ]
                          },
                          "name": {
                            "type": "string",
                            "description": "Its name within the pack. Prefixed for item sprites and GUI sheets."
                          },
                          "status": {
                            "type": "string",
                            "description": "Where the generation got to.",
                            "enum": [
                              "generating",
                              "ready",
                              "error"
                            ]
                          },
                          "displayName": {
                            "type": "string",
                            "description": "The label you gave it, if any."
                          },
                          "prompt": {
                            "type": "string",
                            "description": "What it was generated from."
                          },
                          "error": {
                            "type": "string",
                            "description": "Why it failed. Null unless status is error."
                          },
                          "sizeBytes": {
                            "type": "integer",
                            "description": "Size of the stored file."
                          },
                          "updatedAt": {
                            "type": "string",
                            "description": "ISO 8601."
                          }
                        },
                        "required": [
                          "id",
                          "kind",
                          "name",
                          "status",
                          "updatedAt"
                        ]
                      }
                    },
                    "nextCursor": {
                      "type": "string",
                      "description": "Pass as `cursor` for the next page. Null on the last page."
                    }
                  },
                  "required": [
                    "assets"
                  ]
                },
                "example": {
                  "assets": [
                    {
                      "id": "medieval-keep:texture:mossy_bricks",
                      "kind": "texture",
                      "name": "mossy_bricks",
                      "status": "ready",
                      "displayName": "Mossy Bricks",
                      "prompt": "damp mossy stone bricks",
                      "error": null,
                      "sizeBytes": 1284,
                      "updatedAt": "2026-08-10T16:02:11.000Z"
                    }
                  ],
                  "nextCursor": null
                }
              }
            }
          },
          "default": {
            "description": "Error. Possible `error.code` values: `missing_api_key`, `invalid_api_key`, `plan_required`, `not_found`, `invalid_request`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Every failure from this API has this shape.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable and machine-readable. Branch on this, never on `message`."
                        },
                        "message": {
                          "type": "string",
                          "description": "Human-readable. The wording may change; the code may not."
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "pack",
            "in": "path",
            "required": true,
            "description": "The pack's slug, as returned by the packs endpoints.",
            "schema": {
              "type": "string",
              "description": "The pack's slug, as returned by the packs endpoints.",
              "example": "medieval-keep"
            }
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "description": "Only assets of this storage kind.",
            "schema": {
              "type": "string",
              "description": "Only assets of this storage kind.",
              "enum": [
                "texture",
                "model",
                "font",
                "sound"
              ]
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "How many to return.",
            "schema": {
              "type": "integer",
              "description": "How many to return.",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            }
          },
          {
            "name": "cursor",
            "in": "query",
            "required": false,
            "description": "From the previous response's `nextCursor`.",
            "schema": {
              "type": "integer",
              "description": "From the previous response's `nextCursor`.",
              "minimum": 0
            }
          }
        ]
      }
    },
    "/packs/{pack}/assets/{kind}/{name}": {
      "get": {
        "operationId": "getAssetFile",
        "summary": "Download an asset file",
        "description": "The asset's own bytes, with the matching content type: PNG for textures and icons, JSON for models, Ogg Vorbis for sounds.\n\nRemember the prefixed names: `texture/item:rusted_key`, `texture/gui:shop_menu`, `texture/hud:frostbite`.\n\nAsking before it's ready answers 409 rather than handing back the placeholder that sits there while it generates — a blank PNG that looked like a result is the one genuinely misleading answer available here.",
        "tags": [
          "Packs"
        ],
        "responses": {
          "200": {
            "description": "The file."
          },
          "default": {
            "description": "Error. Possible `error.code` values: `missing_api_key`, `invalid_api_key`, `plan_required`, `not_found`, `invalid_request`, `still_generating`, `generation_failed`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Every failure from this API has this shape.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable and machine-readable. Branch on this, never on `message`."
                        },
                        "message": {
                          "type": "string",
                          "description": "Human-readable. The wording may change; the code may not."
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "pack",
            "in": "path",
            "required": true,
            "description": "The pack's slug, as returned by the packs endpoints.",
            "schema": {
              "type": "string",
              "description": "The pack's slug, as returned by the packs endpoints.",
              "example": "medieval-keep"
            }
          },
          {
            "name": "kind",
            "in": "path",
            "required": true,
            "description": "The storage kind.",
            "schema": {
              "type": "string",
              "description": "The storage kind.",
              "enum": [
                "texture",
                "model",
                "font",
                "sound"
              ]
            }
          },
          {
            "name": "name",
            "in": "path",
            "required": true,
            "description": "The asset's name.",
            "schema": {
              "type": "string",
              "description": "The asset's name.",
              "example": "mossy_bricks"
            }
          }
        ]
      }
    },
    "/packs/{pack}/export": {
      "get": {
        "operationId": "exportPack",
        "summary": "Export the pack as a zip",
        "description": "The finished Java `.zip`, exactly what the Studio's Export button produces. Zipping happens on request rather than being kept warm, so this is slower than the other calls on a large pack. Bedrock `.mcpack` isn't in the API yet.",
        "tags": [
          "Packs"
        ],
        "responses": {
          "200": {
            "description": "A `application/zip` body."
          },
          "default": {
            "description": "Error. Possible `error.code` values: `missing_api_key`, `invalid_api_key`, `plan_required`, `not_found`, `forbidden`, `export_failed`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Every failure from this API has this shape.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable and machine-readable. Branch on this, never on `message`."
                        },
                        "message": {
                          "type": "string",
                          "description": "Human-readable. The wording may change; the code may not."
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "pack",
            "in": "path",
            "required": true,
            "description": "The pack's slug, as returned by the packs endpoints.",
            "schema": {
              "type": "string",
              "description": "The pack's slug, as returned by the packs endpoints.",
              "example": "medieval-keep"
            }
          }
        ]
      }
    },
    "/jobs/{job}": {
      "get": {
        "operationId": "getJob",
        "summary": "Check a generation",
        "description": "A handle looks like `<pack>:<kind>:<name>` and comes back from every generation endpoint.\n\nThere's no jobs table behind this: generation is two-phase, so the asset row is written up front with status `generating` and the runner fills it in. The asset *is* the job record, which is why a handle stays resolvable long after the run finished.\n\nPolling always terminates. A run that dies without recording anything reads as `error` once it passes the stale cutoff.",
        "tags": [
          "Jobs"
        ],
        "responses": {
          "200": {
            "description": "The job's current state. `status` is `generating`, `ready` or `error`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "job": {
                      "type": "string",
                      "description": "The handle you asked about."
                    },
                    "pack": {
                      "type": "string",
                      "description": "The pack it belongs to."
                    },
                    "status": {
                      "type": "string",
                      "description": "Hoisted from the asset so a poll loop needn't reach into it.",
                      "enum": [
                        "generating",
                        "ready",
                        "error"
                      ]
                    },
                    "error": {
                      "type": "string",
                      "description": "Why it failed. Null unless status is error."
                    },
                    "asset": {
                      "type": "object",
                      "description": "The asset itself.",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "Stable id, and the job handle this asset was created under."
                        },
                        "kind": {
                          "type": "string",
                          "description": "Which store it lives in.",
                          "enum": [
                            "texture",
                            "model",
                            "font",
                            "sound"
                          ]
                        },
                        "name": {
                          "type": "string",
                          "description": "Its name within the pack. Prefixed for item sprites and GUI sheets."
                        },
                        "status": {
                          "type": "string",
                          "description": "Where the generation got to.",
                          "enum": [
                            "generating",
                            "ready",
                            "error"
                          ]
                        },
                        "displayName": {
                          "type": "string",
                          "description": "The label you gave it, if any."
                        },
                        "prompt": {
                          "type": "string",
                          "description": "What it was generated from."
                        },
                        "error": {
                          "type": "string",
                          "description": "Why it failed. Null unless status is error."
                        },
                        "sizeBytes": {
                          "type": "integer",
                          "description": "Size of the stored file."
                        },
                        "updatedAt": {
                          "type": "string",
                          "description": "ISO 8601."
                        }
                      },
                      "required": [
                        "id",
                        "kind",
                        "name",
                        "status",
                        "updatedAt"
                      ]
                    }
                  },
                  "required": [
                    "job",
                    "pack",
                    "status",
                    "asset"
                  ]
                },
                "example": {
                  "job": "medieval-keep:texture:mossy_bricks",
                  "pack": "medieval-keep",
                  "status": "ready",
                  "error": null,
                  "asset": {
                    "id": "medieval-keep:texture:mossy_bricks",
                    "kind": "texture",
                    "name": "mossy_bricks",
                    "status": "ready"
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error. Possible `error.code` values: `missing_api_key`, `invalid_api_key`, `plan_required`, `not_found`, `invalid_job_handle`, `job_not_found`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Every failure from this API has this shape.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable and machine-readable. Branch on this, never on `message`."
                        },
                        "message": {
                          "type": "string",
                          "description": "Human-readable. The wording may change; the code may not."
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "job",
            "in": "path",
            "required": true,
            "description": "The job handle.",
            "schema": {
              "type": "string",
              "description": "The job handle.",
              "example": "medieval-keep:texture:mossy_bricks"
            }
          }
        ]
      }
    },
    "/packs/{pack}/textures": {
      "post": {
        "operationId": "generateTexture",
        "summary": "Generate a block texture",
        "description": "Produces a `texture`.\n\n`vanillaTarget` is required when `mode` is `vanilla`; `description` is required when `mode` is `custom`. Setting `faceSlot` generates a single face of a block reskin and needs a `vanillaTarget` that supports per-face textures.",
        "tags": [
          "Generating"
        ],
        "responses": {
          "202": {
            "description": "Accepted. The work runs asynchronously — poll `job` until it leaves `generating`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The asset's name within the pack."
                    },
                    "kind": {
                      "type": "string",
                      "description": "Which store the generated asset lands in.",
                      "enum": [
                        "texture",
                        "model",
                        "font",
                        "sound"
                      ]
                    },
                    "status": {
                      "type": "string",
                      "description": "Always `generating` — nothing is finished when this returns."
                    },
                    "pack": {
                      "type": "string",
                      "description": "The pack it was written into."
                    },
                    "job": {
                      "type": "string",
                      "description": "Poll this at `GET /jobs/{job}` until it leaves `generating`."
                    }
                  },
                  "required": [
                    "id",
                    "kind",
                    "status",
                    "pack",
                    "job"
                  ]
                },
                "example": {
                  "id": "mossy_bricks",
                  "kind": "texture",
                  "job": "medieval-keep:texture:mossy_bricks",
                  "status": "generating",
                  "pack": "medieval-keep"
                }
              }
            }
          },
          "default": {
            "description": "Error. Possible `error.code` values: `missing_api_key`, `invalid_api_key`, `plan_required`, `not_found`, `invalid_request`, `insufficient_credits`, `asset_limit_reached`, `forbidden`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Every failure from this API has this shape.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable and machine-readable. Branch on this, never on `message`."
                        },
                        "message": {
                          "type": "string",
                          "description": "Human-readable. The wording may change; the code may not."
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "pack",
            "in": "path",
            "required": true,
            "description": "The pack's slug, as returned by the packs endpoints.",
            "schema": {
              "type": "string",
              "description": "The pack's slug, as returned by the packs endpoints.",
              "example": "medieval-keep"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prompt": {
                    "type": "string",
                    "description": "What to draw. Describe material and wear, not pixels.",
                    "example": "damp mossy stone bricks, deep green in the mortar"
                  },
                  "size": {
                    "type": "integer",
                    "description": "Output edge length in pixels.",
                    "minimum": 16,
                    "maximum": 128,
                    "example": 16
                  },
                  "mode": {
                    "type": "string",
                    "description": "Replace a vanilla block, or add a texture of your own.",
                    "enum": [
                      "vanilla",
                      "custom"
                    ]
                  },
                  "vanillaTarget": {
                    "type": "string",
                    "description": "The vanilla texture to replace.",
                    "example": "stone_bricks"
                  },
                  "description": {
                    "type": "string",
                    "description": "What this texture is. Required for `custom`."
                  },
                  "name": {
                    "type": "string",
                    "description": "Your label for it."
                  },
                  "faceSlot": {
                    "type": "string",
                    "description": "Generate one face only.",
                    "enum": [
                      "top",
                      "bottom",
                      "side"
                    ]
                  },
                  "referenceId": {
                    "type": "string",
                    "description": "A reference image already uploaded in the Studio. There is no API endpoint to upload one yet."
                  },
                  "referenceStrength": {
                    "type": "number",
                    "description": "How closely to follow the reference. Clamped to this range rather than rejected.",
                    "minimum": 0.05,
                    "maximum": 0.95
                  },
                  "useStyleGuide": {
                    "type": "boolean",
                    "description": "Follow the pack's style guide — its palette, its notes and its reference pictures. Defaults to true, so a pack with a style guide produces assets that match it without this field. Send false for one asset that should deliberately not match. A pack with no style guide, or one switched off, ignores this either way.",
                    "default": true
                  }
                },
                "required": [
                  "prompt",
                  "size",
                  "mode"
                ]
              }
            }
          }
        }
      }
    },
    "/packs/{pack}/models": {
      "post": {
        "operationId": "generateModel",
        "summary": "Generate a 3D model",
        "description": "Produces a `model`. **This is the slow one** — the builder plans the model and constructs it cube by cube, which takes minutes rather than seconds.\n\n`carrierBlockId` decides `directional` on its own when given.",
        "tags": [
          "Generating"
        ],
        "responses": {
          "202": {
            "description": "Accepted. The work runs asynchronously — poll `job` until it leaves `generating`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The asset's name within the pack."
                    },
                    "kind": {
                      "type": "string",
                      "description": "Which store the generated asset lands in.",
                      "enum": [
                        "texture",
                        "model",
                        "font",
                        "sound"
                      ]
                    },
                    "status": {
                      "type": "string",
                      "description": "Always `generating` — nothing is finished when this returns."
                    },
                    "pack": {
                      "type": "string",
                      "description": "The pack it was written into."
                    },
                    "job": {
                      "type": "string",
                      "description": "Poll this at `GET /jobs/{job}` until it leaves `generating`."
                    }
                  },
                  "required": [
                    "id",
                    "kind",
                    "status",
                    "pack",
                    "job"
                  ]
                },
                "example": {
                  "id": "lantern",
                  "kind": "model",
                  "job": "medieval-keep:model:lantern",
                  "status": "generating",
                  "pack": "medieval-keep"
                }
              }
            }
          },
          "default": {
            "description": "Error. Possible `error.code` values: `missing_api_key`, `invalid_api_key`, `plan_required`, `not_found`, `invalid_request`, `insufficient_credits`, `asset_limit_reached`, `forbidden`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Every failure from this API has this shape.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable and machine-readable. Branch on this, never on `message`."
                        },
                        "message": {
                          "type": "string",
                          "description": "Human-readable. The wording may change; the code may not."
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "pack",
            "in": "path",
            "required": true,
            "description": "The pack's slug, as returned by the packs endpoints.",
            "schema": {
              "type": "string",
              "description": "The pack's slug, as returned by the packs endpoints.",
              "example": "medieval-keep"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prompt": {
                    "type": "string",
                    "description": "What to build.",
                    "example": "a wrought iron street lantern with a candle inside"
                  },
                  "name": {
                    "type": "string",
                    "description": "Your label. Falls back to the prompt."
                  },
                  "carrierKind": {
                    "type": "string",
                    "description": "How it's placed in game.",
                    "enum": [
                      "item",
                      "full",
                      "partial"
                    ],
                    "default": "item"
                  },
                  "directional": {
                    "type": "boolean",
                    "description": "Whether it faces the way you placed it."
                  },
                  "carrierBlockId": {
                    "type": "string",
                    "description": "A specific vanilla block to carry it."
                  },
                  "referenceId": {
                    "type": "string",
                    "description": "A reference image already uploaded in the Studio. There is no API endpoint to upload one yet."
                  },
                  "useStyleGuide": {
                    "type": "boolean",
                    "description": "Follow the pack's style guide — its palette, its notes and its reference pictures. Defaults to true, so a pack with a style guide produces assets that match it without this field. Send false for one asset that should deliberately not match. A pack with no style guide, or one switched off, ignores this either way.",
                    "default": true
                  }
                },
                "required": [
                  "prompt"
                ]
              }
            }
          }
        }
      }
    },
    "/packs/{pack}/items": {
      "post": {
        "operationId": "generateItem",
        "summary": "Generate an item",
        "description": "Produces a `texture` named `item:<name>` for a 2D sprite, or a `model` for a 3D one — the response's `kind` and `job` say which.\n\nOmit `target` (or send null) for an item of your own; give a vanilla item id to reskin it. Reskinning one this pack already reskins answers 409: change it in the Studio rather than overwriting it blind. `variant` needs a `target` and Minecraft 1.21.4 or newer.",
        "tags": [
          "Generating"
        ],
        "responses": {
          "202": {
            "description": "Accepted. The work runs asynchronously — poll `job` until it leaves `generating`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The asset's name within the pack."
                    },
                    "kind": {
                      "type": "string",
                      "description": "Which store the generated asset lands in.",
                      "enum": [
                        "texture",
                        "model",
                        "font",
                        "sound"
                      ]
                    },
                    "status": {
                      "type": "string",
                      "description": "Always `generating` — nothing is finished when this returns."
                    },
                    "pack": {
                      "type": "string",
                      "description": "The pack it was written into."
                    },
                    "job": {
                      "type": "string",
                      "description": "Poll this at `GET /jobs/{job}` until it leaves `generating`."
                    }
                  },
                  "required": [
                    "id",
                    "kind",
                    "status",
                    "pack",
                    "job"
                  ]
                },
                "example": {
                  "id": "rusted_key",
                  "kind": "texture",
                  "shape": "sprite",
                  "job": "medieval-keep:texture:item:rusted_key",
                  "status": "generating",
                  "pack": "medieval-keep"
                }
              }
            }
          },
          "default": {
            "description": "Error. Possible `error.code` values: `missing_api_key`, `invalid_api_key`, `plan_required`, `not_found`, `invalid_request`, `insufficient_credits`, `asset_limit_reached`, `forbidden`, `conflict`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Every failure from this API has this shape.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable and machine-readable. Branch on this, never on `message`."
                        },
                        "message": {
                          "type": "string",
                          "description": "Human-readable. The wording may change; the code may not."
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "pack",
            "in": "path",
            "required": true,
            "description": "The pack's slug, as returned by the packs endpoints.",
            "schema": {
              "type": "string",
              "description": "The pack's slug, as returned by the packs endpoints.",
              "example": "medieval-keep"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prompt": {
                    "type": "string",
                    "description": "What to draw or build.",
                    "example": "a rusted iron key with a heart-shaped bow"
                  },
                  "target": {
                    "type": "string",
                    "description": "A vanilla item to reskin. Null or absent means a new item."
                  },
                  "shape": {
                    "type": "string",
                    "description": "A flat sprite, or real geometry.",
                    "enum": [
                      "2d",
                      "3d"
                    ],
                    "default": "2d"
                  },
                  "size": {
                    "type": "integer",
                    "description": "Sprite edge length. 2D only.",
                    "minimum": 16,
                    "maximum": 128
                  },
                  "name": {
                    "type": "string",
                    "description": "Your label. Falls back to the prompt."
                  },
                  "variant": {
                    "type": "boolean",
                    "description": "A custom-model-data variant of `target` rather than a full reskin."
                  },
                  "referenceId": {
                    "type": "string",
                    "description": "A reference image already uploaded in the Studio. There is no API endpoint to upload one yet."
                  },
                  "referenceStrength": {
                    "type": "number",
                    "description": "How closely to follow the reference. Clamped to this range rather than rejected.",
                    "minimum": 0.05,
                    "maximum": 0.95
                  },
                  "useStyleGuide": {
                    "type": "boolean",
                    "description": "Follow the pack's style guide — its palette, its notes and its reference pictures. Defaults to true, so a pack with a style guide produces assets that match it without this field. Send false for one asset that should deliberately not match. A pack with no style guide, or one switched off, ignores this either way.",
                    "default": true
                  }
                },
                "required": [
                  "prompt"
                ]
              }
            }
          }
        }
      }
    },
    "/packs/{pack}/guis": {
      "post": {
        "operationId": "generateGui",
        "summary": "Generate a GUI sheet",
        "description": "Produces a `texture` named `gui:<name>`.\n\n**The easy path is `auto: true`**: a reasoning model plans the whole screen from the prompt — rows, title, materials, buttons, layout — and `target` may be omitted. Without `auto`, you direct everything yourself.\n\n**Image spend**: `elements`, `decorations` and button `icon`s are each their own image call, which is why they share a cap. `texts`, button faces, the title plaque and the frame are composed rather than generated and cost nothing extra.\n\n**Game screens work differently.** `target: \"inventory\"` is the player's own inventory, which a pack reskins by replacing the vanilla file rather than by overlaying a plugin-opened screen. Vanilla owns its layout, so everything about a menu is ignored there — no title, buttons, cards, elements or decorations — and `auto` only chooses the panel and frame materials. A pack may hold one asset per replaced file; a second is refused with `conflict`.",
        "tags": [
          "Generating"
        ],
        "responses": {
          "202": {
            "description": "Accepted. The work runs asynchronously — poll `job` until it leaves `generating`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The asset's name within the pack."
                    },
                    "kind": {
                      "type": "string",
                      "description": "Which store the generated asset lands in.",
                      "enum": [
                        "texture",
                        "model",
                        "font",
                        "sound"
                      ]
                    },
                    "status": {
                      "type": "string",
                      "description": "Always `generating` — nothing is finished when this returns."
                    },
                    "pack": {
                      "type": "string",
                      "description": "The pack it was written into."
                    },
                    "job": {
                      "type": "string",
                      "description": "Poll this at `GET /jobs/{job}` until it leaves `generating`."
                    }
                  },
                  "required": [
                    "id",
                    "kind",
                    "status",
                    "pack",
                    "job"
                  ]
                },
                "example": {
                  "id": "keep_chest",
                  "kind": "texture",
                  "job": "medieval-keep:texture:gui:keep_chest",
                  "status": "generating",
                  "pack": "medieval-keep"
                }
              }
            }
          },
          "default": {
            "description": "Error. Possible `error.code` values: `missing_api_key`, `invalid_api_key`, `plan_required`, `not_found`, `invalid_request`, `insufficient_credits`, `asset_limit_reached`, `forbidden`, `unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Every failure from this API has this shape.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable and machine-readable. Branch on this, never on `message`."
                        },
                        "message": {
                          "type": "string",
                          "description": "Human-readable. The wording may change; the code may not."
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "pack",
            "in": "path",
            "required": true,
            "description": "The pack's slug, as returned by the packs endpoints.",
            "schema": {
              "type": "string",
              "description": "The pack's slug, as returned by the packs endpoints.",
              "example": "medieval-keep"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prompt": {
                    "type": "string",
                    "description": "With `auto`, the whole screen you want; without it, how the panel surface should look.",
                    "example": "an underwater pirate shop"
                  },
                  "auto": {
                    "type": "boolean",
                    "description": "Let the director plan the screen from the prompt alone.",
                    "default": false
                  },
                  "target": {
                    "type": "string",
                    "description": "The vanilla screen to reskin. Required unless `auto` is set (the director picks the chest size).",
                    "example": "chest"
                  },
                  "name": {
                    "type": "string",
                    "description": "Your label."
                  },
                  "title": {
                    "type": "string",
                    "description": "The screen's name, worn per `titleStyle`. Composed from the vanilla font — free."
                  },
                  "titleScale": {
                    "type": "integer",
                    "description": "1 fits long names, 2 is display size.",
                    "enum": [
                      1,
                      2
                    ],
                    "default": 1
                  },
                  "titleStyle": {
                    "type": "string",
                    "description": "How the name is worn: a composed plaque, painted straight onto the panel, or on a drawn signboard.",
                    "enum": [
                      "plaque",
                      "painted",
                      "sign"
                    ],
                    "default": "plaque"
                  },
                  "signPrompt": {
                    "type": "string",
                    "description": "`titleStyle: sign` only — the board to draw (one image call).",
                    "example": "a rough horizontal oak log signboard"
                  },
                  "frame": {
                    "type": "string",
                    "description": "What the frame band is made of — a second material image wrapped round the window.",
                    "example": "worn oak planks with iron nails"
                  },
                  "scene": {
                    "type": "boolean",
                    "description": "Draw the panel as one full-bleed picture instead of a flat material — for screens whose cells hold no items.",
                    "default": false
                  },
                  "buttons": {
                    "type": "array",
                    "description": "Real controls: the face and label are composed (always legible); only an `icon` costs an image call.",
                    "maxItems": 6,
                    "items": {
                      "type": "object",
                      "description": "One button.",
                      "properties": {
                        "slot": {
                          "type": "integer",
                          "description": "Index of the slot its top-left sits on.",
                          "minimum": 0
                        },
                        "label": {
                          "type": "string",
                          "description": "The words on the button. May be empty when `icon` is set.",
                          "maxLength": 24
                        },
                        "icon": {
                          "type": "string",
                          "description": "One small object drawn at 16px beside the label."
                        },
                        "fill": {
                          "type": "string",
                          "description": "Accent for the face, `#rrggbb`. Absent uses the panel's palette."
                        },
                        "wSlots": {
                          "type": "integer",
                          "description": "Width in slots.",
                          "minimum": 1,
                          "maximum": 7,
                          "default": 1
                        },
                        "hSlots": {
                          "type": "integer",
                          "description": "Height in slots.",
                          "minimum": 1,
                          "maximum": 7,
                          "default": 1
                        }
                      },
                      "required": [
                        "slot"
                      ]
                    }
                  },
                  "elements": {
                    "type": "array",
                    "description": "Buttons and icons drawn over the panel. Each is a separate image call.",
                    "maxItems": 6,
                    "items": {
                      "type": "object",
                      "description": "One generated element.",
                      "properties": {
                        "slot": {
                          "type": "integer",
                          "description": "Index of the slot to place it on.",
                          "minimum": 0
                        },
                        "prompt": {
                          "type": "string",
                          "description": "What to draw."
                        },
                        "wSlots": {
                          "type": "integer",
                          "description": "Width in slots.",
                          "minimum": 1,
                          "maximum": 7,
                          "default": 1
                        },
                        "hSlots": {
                          "type": "integer",
                          "description": "Height in slots.",
                          "minimum": 1,
                          "maximum": 7,
                          "default": 1
                        },
                        "kind": {
                          "type": "string",
                          "description": "Artwork fills its box; an icon sits on transparency.",
                          "enum": [
                            "artwork",
                            "icon"
                          ],
                          "default": "artwork"
                        }
                      },
                      "required": [
                        "slot",
                        "prompt"
                      ]
                    }
                  },
                  "texts": {
                    "type": "array",
                    "description": "Lines of text drawn from the vanilla font. Free — no image call.",
                    "maxItems": 12,
                    "items": {
                      "type": "object",
                      "description": "One line of text.",
                      "properties": {
                        "text": {
                          "type": "string",
                          "description": "What it says.",
                          "maxLength": 64
                        },
                        "x": {
                          "type": "integer",
                          "description": "Sheet pixels from the left.",
                          "minimum": 0,
                          "maximum": 255
                        },
                        "y": {
                          "type": "integer",
                          "description": "Sheet pixels from the top.",
                          "minimum": 0,
                          "maximum": 255
                        },
                        "color": {
                          "type": "string",
                          "description": "Hex colour, `#rrggbb`.",
                          "example": "#3f3f3f"
                        },
                        "scale": {
                          "type": "integer",
                          "description": "Whole numbers only — bitmap text at 1.5x is mush.",
                          "minimum": 1,
                          "maximum": 4,
                          "default": 1
                        },
                        "shadow": {
                          "type": "boolean",
                          "description": "Drop shadow behind the glyphs.",
                          "default": true
                        },
                        "align": {
                          "type": "string",
                          "description": "Which edge `x` refers to.",
                          "enum": [
                            "left",
                            "center",
                            "right"
                          ],
                          "default": "left"
                        }
                      },
                      "required": [
                        "text",
                        "x",
                        "y",
                        "color"
                      ]
                    }
                  },
                  "drawSlots": {
                    "type": "boolean",
                    "description": "Draw the item slot boxes.",
                    "default": false
                  },
                  "includePlayerInventory": {
                    "type": "boolean",
                    "description": "Extend the restyle over the player's inventory.",
                    "default": false
                  },
                  "referenceId": {
                    "type": "string",
                    "description": "A reference image already uploaded in the Studio. There is no API endpoint to upload one yet."
                  },
                  "referenceStrength": {
                    "type": "number",
                    "description": "How closely to follow the reference. Clamped to this range rather than rejected.",
                    "minimum": 0.05,
                    "maximum": 0.95
                  },
                  "useStyleGuide": {
                    "type": "boolean",
                    "description": "Follow the pack's style guide — its palette, its notes and its reference pictures. Defaults to true, so a pack with a style guide produces assets that match it without this field. Send false for one asset that should deliberately not match. A pack with no style guide, or one switched off, ignores this either way.",
                    "default": true
                  }
                },
                "required": [
                  "prompt"
                ]
              }
            }
          }
        }
      }
    },
    "/packs/{pack}/hud": {
      "post": {
        "operationId": "generateHud",
        "summary": "Generate the in-game HUD",
        "description": "Produces a `texture` named `hud:<name>` — a kind of its own beside the GUIs: where a GUI is one screen a plugin opens, this is the overlay drawn over the world while nothing is open at all: hearts, hunger, armor, air, the hotbar, the crosshair, the experience bar and the boss bar.\n\n**There are two sets**, chosen with `hud`. `hud` is what you read while you play; `overlays` is the full-screen layers — the vignette at the edge of your vision, the Nausea swirl. A pack may hold one of each.\n\n**One asset, many files.** A HUD set replaces up to 82 real vanilla sprites and is edited afterwards as a single sheet. A pack may hold ONE of each set; a second is refused with `conflict`.\n\n**Image spend is per GROUP, not per file.** Each group costs one image call, and everything in it is derived from that one drawing — one heart becomes all forty-four of vanilla's moods, fills and damage flashes, and one strip becomes the experience bar and every boss bar colour. Pass `groups` to narrow what you pay for.\n\n**The crosshair is picked, not described.** Vanilla’s stays readable by inverting whatever is behind it, which a resource pack cannot do, so this one is drawn light with a dark outline from a fixed set of shapes. `crosshair` chooses which; a prompt would not survive contact with a snowfield.",
        "tags": [
          "Generating"
        ],
        "responses": {
          "202": {
            "description": "Accepted. The work runs asynchronously — poll `job` until it leaves `generating`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The asset's name within the pack."
                    },
                    "kind": {
                      "type": "string",
                      "description": "Which store the generated asset lands in.",
                      "enum": [
                        "texture",
                        "model",
                        "font",
                        "sound"
                      ]
                    },
                    "status": {
                      "type": "string",
                      "description": "Always `generating` — nothing is finished when this returns."
                    },
                    "pack": {
                      "type": "string",
                      "description": "The pack it was written into."
                    },
                    "job": {
                      "type": "string",
                      "description": "Poll this at `GET /jobs/{job}` until it leaves `generating`."
                    }
                  },
                  "required": [
                    "id",
                    "kind",
                    "status",
                    "pack",
                    "job"
                  ]
                },
                "example": {
                  "id": "outbreak_hud",
                  "kind": "texture",
                  "job": "medieval-keep:texture:gui:outbreak_hud",
                  "status": "generating",
                  "pack": "medieval-keep"
                }
              }
            }
          },
          "default": {
            "description": "Error. Possible `error.code` values: `missing_api_key`, `invalid_api_key`, `plan_required`, `not_found`, `invalid_request`, `insufficient_credits`, `asset_limit_reached`, `forbidden`, `unavailable`, `conflict`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Every failure from this API has this shape.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable and machine-readable. Branch on this, never on `message`."
                        },
                        "message": {
                          "type": "string",
                          "description": "Human-readable. The wording may change; the code may not."
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "pack",
            "in": "path",
            "required": true,
            "description": "The pack's slug, as returned by the packs endpoints.",
            "schema": {
              "type": "string",
              "description": "The pack's slug, as returned by the packs endpoints.",
              "example": "medieval-keep"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prompt": {
                    "type": "string",
                    "description": "What the HUD is made of, and what its pips are. Applied to every group.",
                    "example": "rusted field-hospital tin, blood-drop hearts, ration-tin hunger"
                  },
                  "name": {
                    "type": "string",
                    "description": "Your label."
                  },
                  "hud": {
                    "type": "string",
                    "description": "Which set to make. `hud` is the overlay along the bottom and middle of the screen; `overlays` is the full-screen layers (the vignette, the Nausea swirl). They are separate assets and a pack may hold one of each.",
                    "enum": [
                      "hud",
                      "overlays"
                    ],
                    "default": "hud"
                  },
                  "groups": {
                    "type": "array",
                    "description": "Which parts to make — one image call each. Omit for everything available in the chosen set. The enum below is the union across both sets; a group belonging to the other one is refused, as is an unknown or held id. Nothing is ever silently skipped.",
                    "example": [
                      "health",
                      "hunger",
                      "hotbar"
                    ],
                    "items": {
                      "type": "string",
                      "description": "A group id.",
                      "enum": [
                        "hotbar",
                        "health",
                        "hunger",
                        "armor",
                        "air",
                        "experience",
                        "crosshair",
                        "boss_bar",
                        "vignette",
                        "warp",
                        "scope",
                        "frost"
                      ]
                    }
                  },
                  "crosshair": {
                    "type": "string",
                    "description": "Which reticle shape to draw. Composed, so it costs no image call.",
                    "enum": [
                      "cross",
                      "dot",
                      "bracket",
                      "circle",
                      "chevron"
                    ],
                    "default": "cross"
                  },
                  "referenceId": {
                    "type": "string",
                    "description": "A reference image already uploaded in the Studio. There is no API endpoint to upload one yet."
                  },
                  "referenceStrength": {
                    "type": "number",
                    "description": "How closely to follow the reference. Clamped to this range rather than rejected.",
                    "minimum": 0.05,
                    "maximum": 0.95
                  },
                  "useStyleGuide": {
                    "type": "boolean",
                    "description": "Follow the pack's style guide — its palette, its notes and its reference pictures. Defaults to true, so a pack with a style guide produces assets that match it without this field. Send false for one asset that should deliberately not match. A pack with no style guide, or one switched off, ignores this either way.",
                    "default": true
                  }
                },
                "required": [
                  "prompt"
                ]
              }
            }
          }
        }
      }
    },
    "/packs/{pack}/icons": {
      "post": {
        "operationId": "generateIcon",
        "summary": "Generate a font icon",
        "description": "Produces a `font` — a bitmap glyph you can type into chat, signs and books. Omit `width` for a square glyph.",
        "tags": [
          "Generating"
        ],
        "responses": {
          "202": {
            "description": "Accepted. The work runs asynchronously — poll `job` until it leaves `generating`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The asset's name within the pack."
                    },
                    "kind": {
                      "type": "string",
                      "description": "Which store the generated asset lands in.",
                      "enum": [
                        "texture",
                        "model",
                        "font",
                        "sound"
                      ]
                    },
                    "status": {
                      "type": "string",
                      "description": "Always `generating` — nothing is finished when this returns."
                    },
                    "pack": {
                      "type": "string",
                      "description": "The pack it was written into."
                    },
                    "job": {
                      "type": "string",
                      "description": "Poll this at `GET /jobs/{job}` until it leaves `generating`."
                    }
                  },
                  "required": [
                    "id",
                    "kind",
                    "status",
                    "pack",
                    "job"
                  ]
                },
                "example": {
                  "id": "heart",
                  "kind": "font",
                  "job": "medieval-keep:font:heart",
                  "status": "generating",
                  "pack": "medieval-keep"
                }
              }
            }
          },
          "default": {
            "description": "Error. Possible `error.code` values: `missing_api_key`, `invalid_api_key`, `plan_required`, `not_found`, `invalid_request`, `insufficient_credits`, `asset_limit_reached`, `forbidden`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Every failure from this API has this shape.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable and machine-readable. Branch on this, never on `message`."
                        },
                        "message": {
                          "type": "string",
                          "description": "Human-readable. The wording may change; the code may not."
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "pack",
            "in": "path",
            "required": true,
            "description": "The pack's slug, as returned by the packs endpoints.",
            "schema": {
              "type": "string",
              "description": "The pack's slug, as returned by the packs endpoints.",
              "example": "medieval-keep"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prompt": {
                    "type": "string",
                    "description": "What the glyph shows.",
                    "example": "a small red heart"
                  },
                  "height": {
                    "type": "integer",
                    "description": "Glyph height in pixels.",
                    "minimum": 1,
                    "maximum": 256
                  },
                  "width": {
                    "type": "integer",
                    "description": "Glyph width. Square if omitted.",
                    "minimum": 1,
                    "maximum": 256
                  },
                  "name": {
                    "type": "string",
                    "description": "Your label."
                  },
                  "char": {
                    "type": "string",
                    "description": "Pin it to a specific character instead of an assigned codepoint."
                  },
                  "referenceId": {
                    "type": "string",
                    "description": "A reference image already uploaded in the Studio. There is no API endpoint to upload one yet."
                  },
                  "referenceStrength": {
                    "type": "number",
                    "description": "How closely to follow the reference. Clamped to this range rather than rejected.",
                    "minimum": 0.05,
                    "maximum": 0.95
                  },
                  "useStyleGuide": {
                    "type": "boolean",
                    "description": "Follow the pack's style guide — its palette, its notes and its reference pictures. Defaults to true, so a pack with a style guide produces assets that match it without this field. Send false for one asset that should deliberately not match. A pack with no style guide, or one switched off, ignores this either way.",
                    "default": true
                  }
                },
                "required": [
                  "prompt",
                  "height"
                ]
              }
            }
          }
        }
      }
    },
    "/packs/{pack}/sounds": {
      "post": {
        "operationId": "generateSound",
        "summary": "Generate a sound",
        "description": "Produces a `sound`.\n\n**The event name is the feature.** `entity.creeper.primed` replaces the creeper fuse; `custom.gate_open` is a new event you fire by command. A malformed one is refused rather than quietly corrected, because the name decides what the sound does.\n\nSounds take no reference image. Each take is a separate provider call and is charged accordingly.",
        "tags": [
          "Generating"
        ],
        "responses": {
          "202": {
            "description": "Accepted. The work runs asynchronously — poll `job` until it leaves `generating`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "The asset's name within the pack."
                    },
                    "kind": {
                      "type": "string",
                      "description": "Which store the generated asset lands in.",
                      "enum": [
                        "texture",
                        "model",
                        "font",
                        "sound"
                      ]
                    },
                    "status": {
                      "type": "string",
                      "description": "Always `generating` — nothing is finished when this returns."
                    },
                    "pack": {
                      "type": "string",
                      "description": "The pack it was written into."
                    },
                    "job": {
                      "type": "string",
                      "description": "Poll this at `GET /jobs/{job}` until it leaves `generating`."
                    }
                  },
                  "required": [
                    "id",
                    "kind",
                    "status",
                    "pack",
                    "job"
                  ]
                },
                "example": {
                  "id": "gate_open",
                  "kind": "sound",
                  "job": "medieval-keep:sound:gate_open",
                  "status": "generating",
                  "pack": "medieval-keep"
                }
              }
            }
          },
          "default": {
            "description": "Error. Possible `error.code` values: `missing_api_key`, `invalid_api_key`, `plan_required`, `not_found`, `invalid_request`, `insufficient_credits`, `asset_limit_reached`, `forbidden`, `unavailable`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Every failure from this API has this shape.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable and machine-readable. Branch on this, never on `message`."
                        },
                        "message": {
                          "type": "string",
                          "description": "Human-readable. The wording may change; the code may not."
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "pack",
            "in": "path",
            "required": true,
            "description": "The pack's slug, as returned by the packs endpoints.",
            "schema": {
              "type": "string",
              "description": "The pack's slug, as returned by the packs endpoints.",
              "example": "medieval-keep"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "prompt": {
                    "type": "string",
                    "description": "What it should sound like.",
                    "example": "a heavy iron door dragging open"
                  },
                  "event": {
                    "type": "string",
                    "description": "The Minecraft event name this sound answers to.",
                    "example": "custom.gate_open"
                  },
                  "name": {
                    "type": "string",
                    "description": "Your label."
                  },
                  "category": {
                    "type": "string",
                    "description": "Which volume slider controls it.",
                    "enum": [
                      "master",
                      "music",
                      "record",
                      "weather",
                      "block",
                      "hostile",
                      "neutral",
                      "player",
                      "ambient",
                      "voice"
                    ]
                  },
                  "subtitle": {
                    "type": "string",
                    "description": "The subtitle shown when it plays."
                  },
                  "durationSeconds": {
                    "type": "number",
                    "description": "Omit to let the model choose a length.",
                    "minimum": 0.5,
                    "maximum": 30
                  },
                  "promptInfluence": {
                    "type": "number",
                    "description": "How literally to follow the prompt.",
                    "minimum": 0,
                    "maximum": 1
                  },
                  "loop": {
                    "type": "boolean",
                    "description": "Whether it should loop seamlessly.",
                    "default": false
                  },
                  "takeCount": {
                    "type": "integer",
                    "description": "How many alternatives to generate.",
                    "minimum": 1,
                    "maximum": 10,
                    "default": 4
                  }
                },
                "required": [
                  "prompt",
                  "event"
                ]
              }
            }
          }
        }
      }
    },
    "/origin/lookup": {
      "post": {
        "operationId": "lookupOrigin",
        "summary": "Check whether content was generated here",
        "description": "For marketplaces: check whether files uploaded to you were generated by ResourcePack AI. No API key.\n\nSend up to 256 hashes per call. Each returns a result in the order you sent it, so you can pair answers to files without matching on the hash yourself.\n\n`generated` is definitive. **`no_record` is not a negative** — it means only that the content is not in our registry, never that a human made it.\n\n[The Origin check guide](/api-reference/origin) has how to compute the hash, which you must follow exactly or every lookup misses silently.\n\nRate limited to 60 requests a minute per address, since there is no key to count instead.",
        "tags": [
          "Origin check"
        ],
        "responses": {
          "200": {
            "description": "One result per hash asked about.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "description": "In the order the hashes were sent.",
                      "items": {
                        "type": "object",
                        "description": "One verdict.",
                        "properties": {
                          "hash": {
                            "type": "string",
                            "description": "The hash you asked about, lowercased."
                          },
                          "verdict": {
                            "type": "string",
                            "description": "`generated` if we produced this content, `no_record` if it is not in the registry.",
                            "enum": [
                              "generated",
                              "no_record"
                            ]
                          },
                          "form": {
                            "type": "string",
                            "description": "Which canonicalisation produced the hash. Absent on `no_record`.",
                            "enum": [
                              "png",
                              "json",
                              "bytes"
                            ]
                          },
                          "kind": {
                            "type": "string",
                            "description": "What sort of asset it was. Absent on `no_record`.",
                            "enum": [
                              "texture",
                              "model",
                              "font",
                              "sound"
                            ]
                          },
                          "firstSeen": {
                            "type": "string",
                            "description": "ISO 8601 — when this content first left our systems. Absent on `no_record`."
                          }
                        },
                        "required": [
                          "hash",
                          "verdict"
                        ]
                      }
                    },
                    "matched": {
                      "type": "integer",
                      "description": "How many of them we generated."
                    }
                  },
                  "required": [
                    "results",
                    "matched"
                  ]
                },
                "example": {
                  "results": [
                    {
                      "hash": "9f2c1d4a7b3e5f8091a2b3c4d5e6f70819a2b3c4d5e6f70819a2b3c4d5e6f708",
                      "verdict": "generated",
                      "form": "png",
                      "kind": "texture",
                      "firstSeen": "2026-08-14T10:22:06.000Z"
                    },
                    {
                      "hash": "0a1b2c3d4e5f60718293a4b5c6d7e8f90a1b2c3d4e5f60718293a4b5c6d7e8f9",
                      "verdict": "no_record"
                    }
                  ],
                  "matched": 1
                }
              }
            }
          },
          "default": {
            "description": "Error. Possible `error.code` values: `invalid_request`, `invalid_json`, `rate_limited`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Every failure from this API has this shape.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable and machine-readable. Branch on this, never on `message`."
                        },
                        "message": {
                          "type": "string",
                          "description": "Human-readable. The wording may change; the code may not."
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        },
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "hashes": {
                    "type": "array",
                    "description": "Canonical content hashes, 64 hexadecimal characters each. Case is ignored and duplicates are collapsed.",
                    "minItems": 1,
                    "maxItems": 256,
                    "items": {
                      "type": "string",
                      "description": "One hash.",
                      "example": "9f2c1d4a7b3e5f8091a2b3c4d5e6f70819a2b3c4d5e6f70819a2b3c4d5e6f708"
                    }
                  }
                },
                "required": [
                  "hashes"
                ]
              }
            }
          }
        }
      }
    },
    "/origin/range/{prefix}": {
      "get": {
        "operationId": "originRange",
        "summary": "Check without telling us what you asked",
        "description": "The same registry, queried k-anonymously — for a marketplace that would rather not send us the content hashes of what its users upload.\n\nSend the first 5 characters of a hash, get back every fingerprint we hold that starts with them, and match the rest locally.\n\nHashes are computed exactly as for the lookup endpoint, and the same caveat applies: a hit is definitive, a miss is not a negative. See [the Origin check guide](/api-reference/origin).",
        "tags": [
          "Origin check"
        ],
        "responses": {
          "200": {
            "description": "Every fingerprint sharing that prefix.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "prefix": {
                      "type": "string",
                      "description": "The prefix, lowercased."
                    },
                    "suffixes": {
                      "type": "array",
                      "description": "The remainder of each matching hash. Concatenate the prefix to compare.",
                      "items": {
                        "type": "object",
                        "description": "One registered fingerprint.",
                        "properties": {
                          "suffix": {
                            "type": "string",
                            "description": "The hash with the prefix removed."
                          },
                          "form": {
                            "type": "string",
                            "description": "Which canonicalisation produced it.",
                            "enum": [
                              "png",
                              "json",
                              "bytes"
                            ]
                          },
                          "kind": {
                            "type": "string",
                            "description": "What sort of asset it was.",
                            "enum": [
                              "texture",
                              "model",
                              "font",
                              "sound"
                            ]
                          },
                          "firstSeen": {
                            "type": "string",
                            "description": "ISO 8601."
                          }
                        },
                        "required": [
                          "suffix",
                          "form",
                          "kind",
                          "firstSeen"
                        ]
                      }
                    }
                  },
                  "required": [
                    "prefix",
                    "suffixes"
                  ]
                },
                "example": {
                  "prefix": "9f2c1",
                  "suffixes": [
                    {
                      "suffix": "d4a7b3e5f8091a2b3c4d5e6f70819a2b3c4d5e6f70819a2b3c4d5e6f708",
                      "form": "png",
                      "kind": "texture",
                      "firstSeen": "2026-08-14T10:22:06.000Z"
                    }
                  ]
                }
              }
            }
          },
          "default": {
            "description": "Error. Possible `error.code` values: `invalid_request`, `rate_limited`.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Every failure from this API has this shape.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "properties": {
                        "code": {
                          "type": "string",
                          "description": "Stable and machine-readable. Branch on this, never on `message`."
                        },
                        "message": {
                          "type": "string",
                          "description": "Human-readable. The wording may change; the code may not."
                        }
                      },
                      "required": [
                        "code",
                        "message"
                      ]
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        },
        "security": [],
        "parameters": [
          {
            "name": "prefix",
            "in": "path",
            "required": true,
            "description": "The first characters of a canonical content hash, lowercase hexadecimal.",
            "schema": {
              "type": "string",
              "description": "The first characters of a canonical content hash, lowercase hexadecimal.",
              "example": "9f2c1"
            }
          }
        ]
      }
    }
  }
}