{
  "openapi": "3.1.0",
  "info": {
    "title": "Jabbertoon tools for AI assistants and developers",
    "version": "1",
    "summary": "Read Jabbertoon's cartoon moves, characters and looks, check a move, a character or a cartoon, and make a jabbertoon.com link that opens a move or a character.",
    "description": "The same tools as Jabbertoon's MCP server (https://jabbertoon.com/mcp), over plain HTTP. No key and no account. GET answers the read tools whose arguments are plain values; POST a JSON object of arguments to any tool. Nothing sent to validate or share_link is stored or logged; report_problem keeps its report for a person to read. Errors are {code, where, says, fix}. The block language: https://jabbertoon.com/docs/language/",
    "contact": {
      "name": "Jabbertoon",
      "email": "hello@jabbertoon.com",
      "url": "https://jabbertoon.com/for-ai/"
    },
    "license": {
      "name": "Apache-2.0",
      "identifier": "Apache-2.0"
    }
  },
  "servers": [
    {
      "url": "https://jabbertoon.com"
    }
  ],
  "security": [],
  "externalDocs": {
    "description": "Developers: quickstart in curl, Python and JavaScript",
    "url": "https://jabbertoon.com/developers/"
  },
  "x-mcp": {
    "url": "https://jabbertoon.com/mcp",
    "transport": "streamable-http"
  },
  "paths": {
    "/api/list_moves": {
      "get": {
        "operationId": "list_moves",
        "summary": "List Jabbertoon's ready-made cartoon moves",
        "description": "Lists the ready-made moves (animations) a Jabbertoon cartoon character can do, such as walk in, wave hello, hop, bow, slump, or talk with the voice. Each move has an id, a short description, its length in seconds, its page on jabbertoon.com, and links that open it in the block editor or the cartoon studio. A move is not tied to one character: the same move plays on any of the six ready-made characters (person, kid, dog, cat, bird, monster), and some suit some bodies better. Call get_move for a move's program. The optional q keeps the moves whose name, id or description contain all of its words, or that do what a word means (dance finds Groove, scared finds Cower, sleep finds Breathe and Still); notes say which were found by meaning and, for a feeling, the face a say block can show. The filter used is echoed back in filters.",
        "security": [],
        "responses": {
          "200": {
            "description": "What list_moves answers. ok is false when what you sent has problems; they are listed with where, says and fix.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "url"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "url": {
                      "type": "string",
                      "description": "The page that lists every move."
                    },
                    "count": {
                      "type": "integer",
                      "description": "How many moves are listed here."
                    },
                    "total": {
                      "type": "integer",
                      "description": "How many moves there are in all."
                    },
                    "filters": {
                      "type": "object",
                      "description": "The filters this answer used, exactly as given."
                    },
                    "moves": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "slug",
                          "name",
                          "url"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The pack id, e.g. c4c:beh:wave_hello."
                          },
                          "slug": {
                            "type": "string",
                            "description": "The last part of the move's page URL."
                          },
                          "pack_slug": {
                            "type": "string",
                            "description": "The short name used in #p= links, e.g. wave_hello."
                          },
                          "name": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "seconds": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "How long the move's preview plays, in seconds."
                          },
                          "skeleton": {
                            "type": "boolean",
                            "description": "True for the moves that bend chains, reach with hands or turn between views."
                          },
                          "version": {
                            "type": "string"
                          },
                          "license": {
                            "type": "string"
                          },
                          "url": {
                            "type": "string",
                            "description": "The move's page on jabbertoon.com."
                          },
                          "links": {
                            "type": "object",
                            "description": "Links that open the move: blocks (the block editor) and studio (the cartoon studio)."
                          }
                        }
                      }
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "error": {
                      "$ref": "#/components/schemas/Problem"
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/Problem"
          },
          "5XX": {
            "$ref": "#/components/responses/Problem"
          }
        },
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Words to look for in a move's name, id or description, or what the move does, e.g. \"wave\", \"walk in\" or \"dance\". Leave it out to list every move.",
            "schema": {
              "type": "string",
              "maxLength": 100
            }
          }
        ]
      },
      "post": {
        "operationId": "list_moves_post",
        "summary": "List Jabbertoon's ready-made cartoon moves",
        "description": "Lists the ready-made moves (animations) a Jabbertoon cartoon character can do, such as walk in, wave hello, hop, bow, slump, or talk with the voice. Each move has an id, a short description, its length in seconds, its page on jabbertoon.com, and links that open it in the block editor or the cartoon studio. A move is not tied to one character: the same move plays on any of the six ready-made characters (person, kid, dog, cat, bird, monster), and some suit some bodies better. Call get_move for a move's program. The optional q keeps the moves whose name, id or description contain all of its words, or that do what a word means (dance finds Groove, scared finds Cower, sleep finds Breathe and Still); notes say which were found by meaning and, for a feeling, the face a say block can show. The filter used is echoed back in filters.",
        "security": [],
        "responses": {
          "200": {
            "description": "What list_moves answers. ok is false when what you sent has problems; they are listed with where, says and fix.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "url"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "url": {
                      "type": "string",
                      "description": "The page that lists every move."
                    },
                    "count": {
                      "type": "integer",
                      "description": "How many moves are listed here."
                    },
                    "total": {
                      "type": "integer",
                      "description": "How many moves there are in all."
                    },
                    "filters": {
                      "type": "object",
                      "description": "The filters this answer used, exactly as given."
                    },
                    "moves": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "slug",
                          "name",
                          "url"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The pack id, e.g. c4c:beh:wave_hello."
                          },
                          "slug": {
                            "type": "string",
                            "description": "The last part of the move's page URL."
                          },
                          "pack_slug": {
                            "type": "string",
                            "description": "The short name used in #p= links, e.g. wave_hello."
                          },
                          "name": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "seconds": {
                            "type": [
                              "number",
                              "null"
                            ],
                            "description": "How long the move's preview plays, in seconds."
                          },
                          "skeleton": {
                            "type": "boolean",
                            "description": "True for the moves that bend chains, reach with hands or turn between views."
                          },
                          "version": {
                            "type": "string"
                          },
                          "license": {
                            "type": "string"
                          },
                          "url": {
                            "type": "string",
                            "description": "The move's page on jabbertoon.com."
                          },
                          "links": {
                            "type": "object",
                            "description": "Links that open the move: blocks (the block editor) and studio (the cartoon studio)."
                          }
                        }
                      }
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "error": {
                      "$ref": "#/components/schemas/Problem"
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/Problem"
          },
          "5XX": {
            "$ref": "#/components/responses/Problem"
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "q": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "Words to look for in a move's name, id or description, or what the move does, e.g. \"wave\", \"walk in\" or \"dance\". Leave it out to list every move."
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "q": "wave"
              }
            }
          }
        }
      }
    },
    "/api/list_characters": {
      "get": {
        "operationId": "list_characters",
        "summary": "List Jabbertoon's ready-made cartoon characters",
        "description": "Lists the six ready-made cartoon characters (person, kid, dog, cat, bird, monster): how many legs each has, the views it can be drawn in (front, side, back), the colour slots and options a cast entry's look can set, its page on jabbertoon.com, and links that open it in the cartoon studio or the character creator. A cartoon's cast is an object keyed by the ids its blocks name in who, and each entry draws a character by look.template, for example {\"dog\": {\"name\": \"Biscuit\", \"look\": {\"template\": \"dog\", \"style\": \"outlined\"}}}; list_looks gives the styles. The answer also has cartoon_example, a whole talking cartoon to copy and change.",
        "security": [],
        "responses": {
          "200": {
            "description": "What list_characters answers. ok is false when what you sent has problems; they are listed with where, says and fix.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "url"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "url": {
                      "type": "string",
                      "description": "The page that lists every character."
                    },
                    "count": {
                      "type": "integer"
                    },
                    "characters": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "slug",
                          "name",
                          "template",
                          "url"
                        ],
                        "properties": {
                          "slug": {
                            "type": "string"
                          },
                          "id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "The character pack id (c4c:char:<slug>) when the pack is published, else null."
                          },
                          "name": {
                            "type": "string"
                          },
                          "template": {
                            "type": "string",
                            "description": "What a cast entry's look.template says to draw this character."
                          },
                          "legs": {
                            "type": "integer"
                          },
                          "views": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "The views it is drawn in; the first is its own."
                          },
                          "colors": {
                            "type": "array",
                            "description": "The look.colors keys (body, skin, acc), what each paints on this character, and the default colour."
                          },
                          "options": {
                            "type": "array",
                            "description": "The look.options keys this character has, with their values."
                          },
                          "url": {
                            "type": "string",
                            "description": "The character's page on jabbertoon.com."
                          },
                          "links": {
                            "type": "object",
                            "description": "Links that open it: studio (put it in a cartoon) and create (start a new character from it)."
                          }
                        }
                      }
                    },
                    "cast_entry_example": {
                      "type": "object",
                      "description": "One cast entry that draws the first character: the value under a cast id, as in {\"cast\": {\"A\": <this>}}."
                    },
                    "cartoon_example": {
                      "type": "object",
                      "description": "A whole talking cartoon file ({cast, program}) to copy: give it to validate as cartoon."
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "error": {
                      "$ref": "#/components/schemas/Problem"
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/Problem"
          },
          "5XX": {
            "$ref": "#/components/responses/Problem"
          }
        },
        "parameters": []
      },
      "post": {
        "operationId": "list_characters_post",
        "summary": "List Jabbertoon's ready-made cartoon characters",
        "description": "Lists the six ready-made cartoon characters (person, kid, dog, cat, bird, monster): how many legs each has, the views it can be drawn in (front, side, back), the colour slots and options a cast entry's look can set, its page on jabbertoon.com, and links that open it in the cartoon studio or the character creator. A cartoon's cast is an object keyed by the ids its blocks name in who, and each entry draws a character by look.template, for example {\"dog\": {\"name\": \"Biscuit\", \"look\": {\"template\": \"dog\", \"style\": \"outlined\"}}}; list_looks gives the styles. The answer also has cartoon_example, a whole talking cartoon to copy and change.",
        "security": [],
        "responses": {
          "200": {
            "description": "What list_characters answers. ok is false when what you sent has problems; they are listed with where, says and fix.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "url"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "url": {
                      "type": "string",
                      "description": "The page that lists every character."
                    },
                    "count": {
                      "type": "integer"
                    },
                    "characters": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "slug",
                          "name",
                          "template",
                          "url"
                        ],
                        "properties": {
                          "slug": {
                            "type": "string"
                          },
                          "id": {
                            "type": [
                              "string",
                              "null"
                            ],
                            "description": "The character pack id (c4c:char:<slug>) when the pack is published, else null."
                          },
                          "name": {
                            "type": "string"
                          },
                          "template": {
                            "type": "string",
                            "description": "What a cast entry's look.template says to draw this character."
                          },
                          "legs": {
                            "type": "integer"
                          },
                          "views": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            },
                            "description": "The views it is drawn in; the first is its own."
                          },
                          "colors": {
                            "type": "array",
                            "description": "The look.colors keys (body, skin, acc), what each paints on this character, and the default colour."
                          },
                          "options": {
                            "type": "array",
                            "description": "The look.options keys this character has, with their values."
                          },
                          "url": {
                            "type": "string",
                            "description": "The character's page on jabbertoon.com."
                          },
                          "links": {
                            "type": "object",
                            "description": "Links that open it: studio (put it in a cartoon) and create (start a new character from it)."
                          }
                        }
                      }
                    },
                    "cast_entry_example": {
                      "type": "object",
                      "description": "One cast entry that draws the first character: the value under a cast id, as in {\"cast\": {\"A\": <this>}}."
                    },
                    "cartoon_example": {
                      "type": "object",
                      "description": "A whole talking cartoon file ({cast, program}) to copy: give it to validate as cartoon."
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "error": {
                      "$ref": "#/components/schemas/Problem"
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/Problem"
          },
          "5XX": {
            "$ref": "#/components/responses/Problem"
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {},
                "additionalProperties": false
              },
              "example": {}
            }
          }
        }
      }
    },
    "/api/list_looks": {
      "get": {
        "operationId": "list_looks",
        "summary": "List Jabbertoon's art styles (looks) and body shapes",
        "description": "Lists the six art styles (looks) a Jabbertoon character can be drawn in (flat, outlined, soft, storybook, bold, crayon), what each looks like, its page on jabbertoon.com and a studio link that opens the studio in that look; and the three body shapes (classic, big head, tall). A cast entry sets them as look.style and look.shape, for example {\"look\": {\"template\": \"cat\", \"style\": \"crayon\", \"shape\": \"bighead\"}}.",
        "security": [],
        "responses": {
          "200": {
            "description": "What list_looks answers. ok is false when what you sent has problems; they are listed with where, says and fix.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "url"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "url": {
                      "type": "string",
                      "description": "The page that shows every look."
                    },
                    "count": {
                      "type": "integer"
                    },
                    "looks": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "name",
                          "url"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "What look.style says."
                          },
                          "name": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "url": {
                            "type": "string",
                            "description": "The look's page on jabbertoon.com."
                          },
                          "links": {
                            "type": "object",
                            "description": "studio: opens the cartoon studio in this look."
                          }
                        }
                      }
                    },
                    "body_shapes": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "name"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "What look.shape says."
                          },
                          "name": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "error": {
                      "$ref": "#/components/schemas/Problem"
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/Problem"
          },
          "5XX": {
            "$ref": "#/components/responses/Problem"
          }
        },
        "parameters": []
      },
      "post": {
        "operationId": "list_looks_post",
        "summary": "List Jabbertoon's art styles (looks) and body shapes",
        "description": "Lists the six art styles (looks) a Jabbertoon character can be drawn in (flat, outlined, soft, storybook, bold, crayon), what each looks like, its page on jabbertoon.com and a studio link that opens the studio in that look; and the three body shapes (classic, big head, tall). A cast entry sets them as look.style and look.shape, for example {\"look\": {\"template\": \"cat\", \"style\": \"crayon\", \"shape\": \"bighead\"}}.",
        "security": [],
        "responses": {
          "200": {
            "description": "What list_looks answers. ok is false when what you sent has problems; they are listed with where, says and fix.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "url"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "url": {
                      "type": "string",
                      "description": "The page that shows every look."
                    },
                    "count": {
                      "type": "integer"
                    },
                    "looks": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "name",
                          "url"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "What look.style says."
                          },
                          "name": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          },
                          "url": {
                            "type": "string",
                            "description": "The look's page on jabbertoon.com."
                          },
                          "links": {
                            "type": "object",
                            "description": "studio: opens the cartoon studio in this look."
                          }
                        }
                      }
                    },
                    "body_shapes": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": [
                          "id",
                          "name"
                        ],
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "What look.shape says."
                          },
                          "name": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          }
                        }
                      }
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "error": {
                      "$ref": "#/components/schemas/Problem"
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/Problem"
          },
          "5XX": {
            "$ref": "#/components/responses/Problem"
          }
        },
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {},
                "additionalProperties": false
              },
              "example": {}
            }
          }
        }
      }
    },
    "/api/get_move": {
      "get": {
        "operationId": "get_move",
        "summary": "Get one move's program and readable text",
        "description": "Returns one ready-made Jabbertoon move: its block program as JSON (the language Jabbertoon's animation engine plays, described at https://jabbertoon.com/docs/language/), the same program as readable text, its length, its page and links that open it. Name the move by its id (c4c:beh:wave_hello), its short name (wave_hello) or the last part of its page URL. To write your own move, start from one: change the program, check it with validate, then make a link with share_link.",
        "security": [],
        "responses": {
          "200": {
            "description": "What get_move answers. ok is false when what you sent has problems; they are listed with where, says and fix.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "url"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "url": {
                      "type": "string",
                      "description": "The move's page on jabbertoon.com (the list of moves when the move is not found)."
                    },
                    "id": {
                      "type": "string"
                    },
                    "slug": {
                      "type": "string"
                    },
                    "pack_slug": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "description": {
                      "type": "string"
                    },
                    "seconds": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "skeleton": {
                      "type": "boolean"
                    },
                    "version": {
                      "type": "string"
                    },
                    "license": {
                      "type": "string"
                    },
                    "content_hash": {
                      "type": "string"
                    },
                    "links": {
                      "type": "object"
                    },
                    "program": {
                      "type": "object",
                      "description": "The move's block program (JSON)."
                    },
                    "text": {
                      "type": "string",
                      "description": "The same program as readable text, one block per line."
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "error": {
                      "$ref": "#/components/schemas/Problem"
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/Problem"
          },
          "5XX": {
            "$ref": "#/components/responses/Problem"
          }
        },
        "parameters": [
          {
            "name": "move",
            "in": "query",
            "required": true,
            "description": "The move's id (c4c:beh:wave_hello), short name (wave_hello) or page slug, as list_moves gives them.",
            "schema": {
              "type": "string",
              "maxLength": 100
            }
          }
        ]
      },
      "post": {
        "operationId": "get_move_post",
        "summary": "Get one move's program and readable text",
        "description": "Returns one ready-made Jabbertoon move: its block program as JSON (the language Jabbertoon's animation engine plays, described at https://jabbertoon.com/docs/language/), the same program as readable text, its length, its page and links that open it. Name the move by its id (c4c:beh:wave_hello), its short name (wave_hello) or the last part of its page URL. To write your own move, start from one: change the program, check it with validate, then make a link with share_link.",
        "security": [],
        "responses": {
          "200": {
            "description": "What get_move answers. ok is false when what you sent has problems; they are listed with where, says and fix.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "url"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "url": {
                      "type": "string",
                      "description": "The move's page on jabbertoon.com (the list of moves when the move is not found)."
                    },
                    "id": {
                      "type": "string"
                    },
                    "slug": {
                      "type": "string"
                    },
                    "pack_slug": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "description": {
                      "type": "string"
                    },
                    "seconds": {
                      "type": [
                        "number",
                        "null"
                      ]
                    },
                    "skeleton": {
                      "type": "boolean"
                    },
                    "version": {
                      "type": "string"
                    },
                    "license": {
                      "type": "string"
                    },
                    "content_hash": {
                      "type": "string"
                    },
                    "links": {
                      "type": "object"
                    },
                    "program": {
                      "type": "object",
                      "description": "The move's block program (JSON)."
                    },
                    "text": {
                      "type": "string",
                      "description": "The same program as readable text, one block per line."
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "error": {
                      "$ref": "#/components/schemas/Problem"
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/Problem"
          },
          "5XX": {
            "$ref": "#/components/responses/Problem"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "move"
                ],
                "properties": {
                  "move": {
                    "type": "string",
                    "maxLength": 100,
                    "description": "The move's id (c4c:beh:wave_hello), short name (wave_hello) or page slug, as list_moves gives them."
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "move": "wave_hello"
              }
            }
          }
        }
      }
    },
    "/api/validate": {
      "post": {
        "operationId": "validate",
        "summary": "Check a Jabbertoon program, character, pack or cartoon",
        "description": "Checks a Jabbertoon block program (a move, a scene or a cartoon), a character, a pack, or a saved cartoon file with Jabbertoon's own validator, the same checks the studio, the character creator and the block editor make. Give exactly one of program, character, pack or cartoon. A talking cartoon is {\"cast\": {\"dog\": {\"name\": \"Biscuit\", \"look\": {\"template\": \"dog\"}}}, \"program\": {\"v\": 1, \"kind\": \"cartoon\", \"scripts\": [{\"hat\": {\"on\": \"scene\", \"name\": \"Hello\"}, \"body\": [{\"op\": \"say\", \"who\": \"dog\", \"text\": \"Hi!\"}]}]}}: the cast is an object keyed by ids, who names a cast id, every script starts with a scene hat, and a scene's blocks are say {who, text}, does {who, behaviour} (a move id from list_moves, or an inline move), enter, exit, place, cut, caption and mood, with wait, repeat and together. A move is a program of kind \"behaviour\" (get_move gives ready-made ones). The answer has ok, error_count, warning_count, and the errors and warnings (the first 50 of each, in order) as {code, where, says, fix}: where is the path of the field (e.g. scripts[0].body[2]), says is what is wrong, fix is how to fix it there when the checker knows, keeping the block's own words, speaker and fields. Fix the errors and call validate again until ok is true; warnings do not stop a program from playing, but say what the site will not do: hats that never fire on jabbertoon.com today (touch, beat, loud, every) or only in the block editor (key, click), moves that do not exist, and looks it cannot draw. Nothing you send is stored or logged.",
        "security": [],
        "responses": {
          "200": {
            "description": "What validate answers. ok is false when what you sent has problems; they are listed with where, says and fix.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "url"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "description": "True when there are no errors."
                    },
                    "url": {
                      "type": "string",
                      "description": "The page that describes this format."
                    },
                    "checked": {
                      "type": "string",
                      "description": "What was checked: program, character, pack or cartoon."
                    },
                    "kind": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "The program's kind (behaviour, scene, cartoon), character, or the pack's type."
                    },
                    "errors": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Problem"
                      },
                      "description": "The errors, in order: the first 50 at most (error_count says how many there are)."
                    },
                    "error_count": {
                      "type": "integer",
                      "description": "How many errors the checks found."
                    },
                    "warnings": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Problem"
                      },
                      "description": "The warnings, in order: the first 50 at most (warning_count says how many there are)."
                    },
                    "warning_count": {
                      "type": "integer",
                      "description": "How many warnings the checks found."
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "error": {
                      "$ref": "#/components/schemas/Problem"
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/Problem"
          },
          "5XX": {
            "$ref": "#/components/responses/Problem"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "program": {
                    "type": "object",
                    "description": "A block program: {\"v\": 1, \"kind\": \"behaviour\" | \"scene\" | \"cartoon\", \"scripts\": [...]}, as get_move returns. A move is kind \"behaviour\". The language: https://jabbertoon.com/docs/language/"
                  },
                  "pack": {
                    "type": "object",
                    "description": "A whole pack: the manifest (pack, id, type, version, name, author, license, remixable, derived_from, content_hash) and its content. The format: https://jabbertoon.com/docs/packs/"
                  },
                  "cartoon": {
                    "type": "object",
                    "description": "A saved cartoon file: {\"cast\": {\"<id>\": {\"name\", \"look\": {\"template\", \"style\", \"shape\", \"colors\"}, \"at\": {\"x\", \"y\", \"h\", \"facing\"}}}, \"places\"?, \"program\"}, where program is a kind \"cartoon\" program. list_characters returns a whole one (cartoon_example)."
                  },
                  "character": {
                    "type": "object",
                    "description": "A character of your own, as share_link takes it: {\"name\": \"...\", \"content\": {...}}, the content of a character pack (tree, legs, kind, height, footprint, ...), or a whole character pack. Its tree is checked part by part. The format: https://jabbertoon.com/docs/packs/"
                  }
                },
                "minProperties": 1,
                "maxProperties": 1,
                "additionalProperties": false
              },
              "example": {
                "cartoon": {
                  "cast": {
                    "dog": {
                      "name": "Biscuit",
                      "look": {
                        "template": "dog",
                        "style": "outlined"
                      }
                    },
                    "cat": {
                      "name": "Mia",
                      "look": {
                        "template": "cat",
                        "style": "outlined"
                      },
                      "at": {
                        "x": 0.7,
                        "facing": -1
                      }
                    }
                  },
                  "program": {
                    "v": 1,
                    "kind": "cartoon",
                    "name": "Hello, Mia",
                    "scripts": [
                      {
                        "hat": {
                          "on": "scene",
                          "name": "Hello"
                        },
                        "body": [
                          {
                            "op": "enter",
                            "who": "dog",
                            "from": "left",
                            "x": 0.3
                          },
                          {
                            "op": "does",
                            "who": "dog",
                            "behaviour": "c4c:beh:wave_hello"
                          },
                          {
                            "op": "say",
                            "who": "dog",
                            "text": "Hi, Mia! Do you want to play?"
                          },
                          {
                            "op": "does",
                            "who": "cat",
                            "behaviour": "c4c:beh:bounce"
                          },
                          {
                            "op": "say",
                            "who": "cat",
                            "text": "Yes, please!",
                            "mood": "happy"
                          }
                        ]
                      }
                    ]
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/share_link": {
      "post": {
        "operationId": "share_link",
        "summary": "Make a jabbertoon.com link that opens a move or a character",
        "description": "Turns a Jabbertoon move (a block program of kind \"behaviour\") or a character into a jabbertoon.com link the person can open in their browser. Everything travels inside the link after the #, so nothing is uploaded or stored, by Jabbertoon or by this tool. A move opens in the block editor, where it plays on a character (links.studio adds it to the person's moves in the cartoon studio); a character opens in the cartoon studio (links.create opens it in the character creator). Give exactly one of program, cartoon or character. No link plays a scene or a whole cartoon yet: for a program of kind \"scene\" or \"cartoon\", or a cartoon file, the answer is ok false with error code \"not_yet\" and no link (validate checks one now). A move or a character is checked first: one with errors gets ok false and the errors (as validate gives them) instead of a link.",
        "security": [],
        "responses": {
          "200": {
            "description": "What share_link answers. ok is false when what you sent has problems; they are listed with where, says and fix.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "url"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "url": {
                      "type": "string",
                      "description": "The jabbertoon.com page the link opens (with not_yet, the page that says what links open today)."
                    },
                    "kind": {
                      "type": [
                        "string",
                        "null"
                      ],
                      "description": "behaviour, scene, cartoon or character."
                    },
                    "link": {
                      "type": "string",
                      "description": "The link to give the person."
                    },
                    "links": {
                      "type": "object",
                      "description": "Every page that opens it: blocks, studio, create."
                    },
                    "code": {
                      "type": "string",
                      "description": "The share code: base64url of the UTF-8 canonical JSON, no padding; the part after #c=."
                    },
                    "length": {
                      "type": "integer",
                      "description": "The link's length in characters."
                    },
                    "errors": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Problem"
                      },
                      "description": "The errors, in order: the first 50 at most (error_count says how many there are)."
                    },
                    "error_count": {
                      "type": "integer",
                      "description": "How many errors the checks found."
                    },
                    "warnings": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Problem"
                      },
                      "description": "The warnings, in order: the first 50 at most (warning_count says how many there are)."
                    },
                    "warning_count": {
                      "type": "integer",
                      "description": "How many warnings the checks found."
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "error": {
                      "$ref": "#/components/schemas/Problem"
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/Problem"
          },
          "5XX": {
            "$ref": "#/components/responses/Problem"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "program": {
                    "type": "object",
                    "description": "A move: a block program {\"v\": 1, \"kind\": \"behaviour\", \"scripts\": [...]}, as get_move returns. A program of kind \"scene\" or \"cartoon\" gets not_yet."
                  },
                  "cartoon": {
                    "type": "object",
                    "description": "A saved cartoon file: {\"cast\"?, \"places\"?, \"program\"}. Links that play one are coming in the next release: the answer is not_yet."
                  },
                  "character": {
                    "type": "object",
                    "description": "A character: {\"name\": \"...\", \"content\": {...}}, the content of a character pack (tree, legs, kind, height, footprint, ...), or a whole character pack."
                  }
                },
                "minProperties": 1,
                "maxProperties": 1,
                "additionalProperties": false
              },
              "example": {
                "program": {
                  "v": 1,
                  "kind": "behaviour",
                  "name": "Happy bob",
                  "scripts": [
                    {
                      "body": [
                        {
                          "op": "bob",
                          "amp": 12
                        },
                        {
                          "op": "swingPart",
                          "part": "arms",
                          "deg": 30
                        }
                      ]
                    }
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/api/report_problem": {
      "post": {
        "operationId": "report_problem",
        "summary": "Tell Jabbertoon something is wrong",
        "description": "Reports a problem with Jabbertoon's tools or content to the people who run it: a tool answer that is wrong, a validator that refused a good program or passed a bad one, a move that looks wrong on a character, a link that does not open, docs that say something the engine does not do, or something missing. Unlike the other tools, this one keeps what you send: the report (kind, item, the request that produced it, and your note) is saved for a person to read. Never put personal details in it: no names, email addresses, or anything about the person you are helping.",
        "security": [],
        "responses": {
          "200": {
            "description": "What report_problem answers. ok is false when what you sent has problems; they are listed with where, says and fix.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": [
                    "ok",
                    "url"
                  ],
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "url": {
                      "type": "string",
                      "description": "The page about Jabbertoon's tools for AI assistants."
                    },
                    "status": {
                      "type": "string",
                      "description": "received"
                    },
                    "report_id": {
                      "type": "string"
                    },
                    "says": {
                      "type": "string"
                    },
                    "removed": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      },
                      "description": "What was taken out of the report before it was saved (an email address, for example)."
                    },
                    "notes": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    },
                    "error": {
                      "$ref": "#/components/schemas/Problem"
                    }
                  }
                }
              }
            }
          },
          "4XX": {
            "$ref": "#/components/responses/Problem"
          },
          "5XX": {
            "$ref": "#/components/responses/Problem"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "kind"
                ],
                "properties": {
                  "kind": {
                    "type": "string",
                    "enum": [
                      "wrong_answer",
                      "validator_wrong",
                      "move_looks_wrong",
                      "link_does_not_open",
                      "docs_wrong",
                      "missing",
                      "other"
                    ],
                    "description": "What kind of problem it is."
                  },
                  "item": {
                    "type": "string",
                    "maxLength": 200,
                    "description": "What it is about: a move, character or look (c4c:beh:bow, dog, crayon), a tool name, or a jabbertoon.com page."
                  },
                  "request": {
                    "type": "object",
                    "description": "The tool call that produced the problem, as {\"tool\": \"...\", \"arguments\": {...}}. It is kept with the report, cut to 4,000 characters."
                  },
                  "note": {
                    "type": "string",
                    "maxLength": 1000,
                    "description": "What was wrong, in a sentence or two. No personal details."
                  }
                },
                "additionalProperties": false
              },
              "example": {
                "kind": "wrong_answer",
                "item": "list_moves",
                "note": "The description of a move does not match what it does."
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "required": [
          "code",
          "where",
          "says",
          "fix"
        ],
        "properties": {
          "code": {
            "type": "string"
          },
          "where": {
            "type": [
              "string",
              "null"
            ]
          },
          "says": {
            "type": "string"
          },
          "fix": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      }
    },
    "responses": {
      "Problem": {
        "description": "A request the server cannot use (400 bad_arguments, 404 not_found, 405, 413 too_large, 415, 503 busy or timeout: try again after Retry-After).",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "required": [
                "ok",
                "url",
                "error"
              ],
              "properties": {
                "ok": {
                  "const": false
                },
                "url": {
                  "type": "string"
                },
                "error": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    }
  }
}
