{
  "openapi": "3.1.0",
  "info": {
    "title": "Kiori API",
    "version": "1.0.0",
    "description": "Brains for characters: memory, personality and who-knows-what for character AI. Every call needs a project key (Authorization: Bearer kio_...) unless marked otherwise. Wherever an id of ours goes, your own (external_id) works too."
  },
  "servers": [
    {
      "url": "https://api.kiori.io",
      "description": "The hosted beta"
    },
    {
      "url": "http://127.0.0.1:7700",
      "description": "Self-hosted"
    }
  ],
  "security": [
    {
      "key": []
    }
  ],
  "tags": [
    {
      "name": "Turn",
      "description": "The easy way in"
    },
    {
      "name": "Characters"
    },
    {
      "name": "Stories"
    },
    {
      "name": "Project"
    }
  ],
  "paths": {
    "/v1/turn": {
      "post": {
        "summary": "One call per turn",
        "description": "The story (made on the first call from your ids), your messages synced (new, edited, rerolled, deleted), and each character's context for this moment.",
        "tags": [
          "Turn"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TurnInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TurnResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/chat/completions": {
      "post": {
        "summary": "The drop-in: OpenAI-compatible chat",
        "description": "Send your usual chat completion request here instead of to your provider. Kiori syncs the messages, adds each character's mind to the system prompt, passes the request on to your model with your key, and records the reply. Streaming works; with check (default: when the player brings up the past) the reply is held and checked first. Say which story it is with X-Kiori-Story (and X-Kiori-Characters to make it), or \"kiori\": { story, characters, player, check } in the body.",
        "tags": [
          "Turn"
        ],
        "parameters": [
          {
            "name": "X-Kiori-Story",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Kiori-Characters",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Kiori-Player",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Kiori-Check",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Kiori-Upstream-Url",
            "in": "header",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "X-Kiori-Upstream-Key",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "model": {
                    "type": "string"
                  },
                  "messages": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {}
                    }
                  },
                  "stream": {
                    "type": "boolean"
                  },
                  "kiori": {
                    "type": "object",
                    "properties": {
                      "story": {
                        "type": "string"
                      },
                      "characters": {
                        "type": "array",
                        "items": {
                          "type": "string"
                        }
                      },
                      "player": {
                        "type": "string"
                      },
                      "check": {
                        "type": "string",
                        "enum": [
                          "auto",
                          "true",
                          "false"
                        ]
                      }
                    }
                  }
                },
                "required": [
                  "messages"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {},
                  "description": "Your provider's answer, as it gave it (with the checked reply when held)"
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/models": {
      "get": {
        "summary": "Your provider's models, passed on",
        "tags": [
          "Turn"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {}
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/characters": {
      "get": {
        "summary": "List characters",
        "tags": [
          "Characters"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "id": {
                        "type": "string"
                      },
                      "name": {
                        "type": "string"
                      },
                      "who": {
                        "type": "string"
                      },
                      "origin": {
                        "type": "string"
                      },
                      "status": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Build a brain",
        "description": "Returns at once with status \"building\" (about a minute and a half), unless wait is true.",
        "tags": [
          "Characters"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BuildInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Character"
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/characters/{character}": {
      "get": {
        "summary": "A character",
        "tags": [
          "Characters"
        ],
        "parameters": [
          {
            "name": "character",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Our id or your own (external_id)"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Character"
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "summary": "Change a character",
        "description": "A new name keeps the old one as an alias.",
        "tags": [
          "Characters"
        ],
        "parameters": [
          {
            "name": "character",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Our id or your own (external_id)"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "aliases": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "pronouns": {
                    "type": "string"
                  },
                  "card": {
                    "$ref": "#/components/schemas/Card"
                  },
                  "personality": {
                    "type": "object",
                    "properties": {}
                  },
                  "external_id": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Character"
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete a character",
        "tags": [
          "Characters"
        ],
        "parameters": [
          {
            "name": "character",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Our id or your own (external_id)"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {}
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/characters/{character}/memories": {
      "get": {
        "summary": "Their memories, or the recall order for a moment (q)",
        "tags": [
          "Characters"
        ],
        "parameters": [
          {
            "name": "character",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Our id or your own (external_id)"
          },
          {
            "name": "story",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "kind",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "q",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Memory"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Write memories yourself",
        "tags": [
          "Characters"
        ],
        "parameters": [
          {
            "name": "character",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Our id or your own (external_id)"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "memories": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "kind": {
                          "type": "string"
                        },
                        "title": {
                          "type": "string"
                        },
                        "body": {
                          "type": "string"
                        },
                        "keys": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "about": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "importance": {
                          "type": "number"
                        },
                        "emotion": {
                          "type": "number"
                        }
                      }
                    }
                  },
                  "story": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {}
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/characters/{character}/graph": {
      "get": {
        "summary": "Nodes and edges for a graph view",
        "tags": [
          "Characters"
        ],
        "parameters": [
          {
            "name": "character",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Our id or your own (external_id)"
          },
          {
            "name": "story",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {}
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/characters/{character}/sleep": {
      "post": {
        "summary": "Fade, gist and merge memories",
        "tags": [
          "Characters"
        ],
        "parameters": [
          {
            "name": "character",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Our id or your own (external_id)"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "story": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {}
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/characters/{character}/export": {
      "get": {
        "summary": "The brain as an Obsidian vault (zip)",
        "tags": [
          "Characters"
        ],
        "parameters": [
          {
            "name": "character",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Our id or your own (external_id)"
          },
          {
            "name": "story",
            "in": "query",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {}
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/memories/{memory}": {
      "patch": {
        "summary": "Edit a memory",
        "tags": [
          "Characters"
        ],
        "parameters": [
          {
            "name": "memory",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "title": {
                    "type": "string"
                  },
                  "body": {
                    "type": "string"
                  },
                  "keys": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "importance": {
                    "type": "number"
                  },
                  "strength": {
                    "type": "number"
                  },
                  "status": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Memory"
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete a memory",
        "tags": [
          "Characters"
        ],
        "parameters": [
          {
            "name": "memory",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {}
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/stories": {
      "get": {
        "summary": "List stories",
        "tags": [
          "Stories"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Story"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Start a story (or get it back by external_id)",
        "tags": [
          "Stories"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/StoryInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Story"
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/stories/{story}": {
      "get": {
        "summary": "A story",
        "tags": [
          "Stories"
        ],
        "parameters": [
          {
            "name": "story",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Our id or your own (external_id)"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Story"
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete a story and everything it taught",
        "tags": [
          "Stories"
        ],
        "parameters": [
          {
            "name": "story",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Our id or your own (external_id)"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {}
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/stories/{story}/characters": {
      "post": {
        "summary": "Add characters",
        "tags": [
          "Stories"
        ],
        "parameters": [
          {
            "name": "story",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Our id or your own (external_id)"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "characters": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Story"
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/stories/{story}/events": {
      "get": {
        "summary": "Events",
        "tags": [
          "Stories"
        ],
        "parameters": [
          {
            "name": "story",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Our id or your own (external_id)"
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Event"
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "summary": "Record what happened",
        "tags": [
          "Stories"
        ],
        "parameters": [
          {
            "name": "story",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Our id or your own (external_id)"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "events": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/EventInput"
                    }
                  }
                },
                "required": [
                  "events"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "from": {
                      "type": "integer"
                    },
                    "to": {
                      "type": "integer"
                    },
                    "learning": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Rewind: remove event N and everything after it",
        "tags": [
          "Stories"
        ],
        "parameters": [
          {
            "name": "story",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Our id or your own (external_id)"
          },
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1
            },
            "required": true
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "removed_from": {
                      "type": "integer"
                    },
                    "relearning": {
                      "type": "integer"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/stories/{story}/sync": {
      "post": {
        "summary": "Sync your messages",
        "description": "Your messages as they are now, oldest first: new ones are recorded; from the first edited, rerolled or deleted one the story is rewound.",
        "tags": [
          "Stories"
        ],
        "parameters": [
          {
            "name": "story",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Our id or your own (external_id)"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "messages": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/ChatMessage"
                    }
                  }
                },
                "required": [
                  "messages"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SyncResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/stories/{story}/context": {
      "post": {
        "summary": "What each character brings to this moment",
        "tags": [
          "Stories"
        ],
        "parameters": [
          {
            "name": "story",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Our id or your own (external_id)"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "allOf": [
                  {
                    "$ref": "#/components/schemas/ContextOptions"
                  },
                  {
                    "type": "object",
                    "properties": {
                      "messages": {
                        "type": "array",
                        "items": {}
                      }
                    }
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "story": {
                      "type": "string"
                    },
                    "characters": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/CharacterContext"
                      }
                    },
                    "warnings": {
                      "type": "array",
                      "items": {
                        "type": "string"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/stories/{story}/check": {
      "post": {
        "summary": "The auditor: check a draft before it is shown",
        "tags": [
          "Stories"
        ],
        "parameters": [
          {
            "name": "story",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Our id or your own (external_id)"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CheckInput"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CheckResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/stories/{story}/learn": {
      "post": {
        "summary": "Learn everything new now",
        "tags": [
          "Stories"
        ],
        "parameters": [
          {
            "name": "story",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Our id or your own (external_id)"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "wait": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LearnResult"
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/stories/{story}/rebuild": {
      "post": {
        "summary": "Forget what this story taught and learn it again",
        "tags": [
          "Stories"
        ],
        "parameters": [
          {
            "name": "story",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Our id or your own (external_id)"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "wait": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {}
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/stories/{story}/witnesses": {
      "get": {
        "summary": "Scenes with who was present",
        "tags": [
          "Stories"
        ],
        "parameters": [
          {
            "name": "story",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            },
            "description": "Our id or your own (external_id)"
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {}
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/project": {
      "get": {
        "summary": "The project, its settings and keys",
        "tags": [
          "Project"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {}
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "patch": {
        "summary": "Change the name or settings (lore, upstream)",
        "tags": [
          "Project"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  },
                  "settings": {
                    "type": "object",
                    "properties": {
                      "lore": {
                        "type": "string"
                      },
                      "upstream": {
                        "type": "object",
                        "properties": {
                          "url": {
                            "type": "string"
                          },
                          "key": {
                            "type": "string"
                          }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {}
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/project/keys": {
      "post": {
        "summary": "A new API key (shown once)",
        "tags": [
          "Project"
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "label": {
                    "type": "string"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "key": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/project/keys/{prefix}": {
      "delete": {
        "summary": "Revoke a key",
        "tags": [
          "Project"
        ],
        "parameters": [
          {
            "name": "prefix",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {}
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/usage": {
      "get": {
        "summary": "Model calls and cost",
        "tags": [
          "Project"
        ],
        "parameters": [
          {
            "name": "days",
            "in": "query",
            "schema": {
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {}
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/personality": {
      "get": {
        "summary": "The 41 personality dimensions and the archetypes",
        "tags": [
          "Characters"
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {}
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Bad or missing key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "security": []
      }
    },
    "/v1/access": {
      "post": {
        "summary": "Ask for access (no key needed)",
        "tags": [
          "Project"
        ],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string"
                  },
                  "name": {
                    "type": "string"
                  },
                  "company": {
                    "type": "string"
                  },
                  "use_case": {
                    "type": "string"
                  }
                },
                "required": [
                  "email"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Too many requests from this address"
          }
        }
      }
    },
    "/health": {
      "get": {
        "summary": "Is it running",
        "security": [],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean"
                    },
                    "name": {
                      "type": "string"
                    },
                    "version": {
                      "type": "string"
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "key": {
        "type": "http",
        "scheme": "bearer",
        "description": "A project key: kio_..."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "message": {
                "type": "string"
              },
              "code": {
                "type": "string",
                "description": "BAD_REQUEST, UNAUTHORIZED, NOT_FOUND, CONFLICT, CREDITS, PROVIDER, NO_KEY, ..."
              }
            }
          }
        }
      },
      "Card": {
        "type": "object",
        "properties": {
          "who": {
            "type": "string"
          },
          "looks": {
            "type": "string"
          },
          "personality": {
            "type": "string"
          },
          "voice": {
            "type": "string"
          },
          "core": {
            "type": "string"
          },
          "scenario": {
            "type": "string"
          },
          "first_message": {
            "type": "string"
          },
          "examples": {
            "type": "string"
          }
        }
      },
      "Character": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "external_id": {
            "type": [
              "string",
              "null"
            ],
            "description": "Your own id"
          },
          "name": {
            "type": "string"
          },
          "aliases": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "pronouns": {
            "type": "string",
            "enum": [
              "she",
              "he",
              "they"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "building",
              "ready",
              "failed"
            ]
          },
          "status_detail": {
            "type": "string"
          },
          "card": {
            "$ref": "#/components/schemas/Card"
          },
          "personality": {
            "type": "object",
            "additionalProperties": {
              "type": "integer",
              "minimum": 0,
              "maximum": 100
            },
            "description": "41 values, 50 = an average person"
          },
          "profile": {
            "type": "string"
          },
          "attachment": {
            "type": "string"
          },
          "deviations": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {}
            }
          },
          "memory_counts": {
            "type": "object",
            "properties": {
              "core": {
                "type": "integer"
              },
              "stories": {
                "type": "integer"
              }
            }
          },
          "origin": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          },
          "existing": {
            "type": "boolean",
            "description": "Set when create found this character by external_id"
          }
        }
      },
      "BuildInput": {
        "type": "object",
        "properties": {
          "external_id": {
            "type": "string",
            "description": "Your own id: creating again with it gives the same character back"
          },
          "character_card": {
            "description": "A Tavern / SillyTavern character card (v1, v2, v3) as JSON, or a card PNG in base64",
            "oneOf": [
              {
                "type": "object"
              },
              {
                "type": "string"
              }
            ]
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string",
            "description": "Who they are; the more, the more faithful"
          },
          "lore": {
            "type": "string",
            "description": "Extra canon for this character"
          },
          "pronouns": {
            "type": "string",
            "enum": [
              "she",
              "he",
              "they"
            ]
          },
          "archetype": {
            "type": "string"
          },
          "personality": {
            "type": "object",
            "additionalProperties": {
              "type": "integer"
            }
          },
          "wait": {
            "type": "boolean",
            "description": "Hold the request until the brain is built"
          }
        }
      },
      "Memory": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "character_id": {
            "type": "string"
          },
          "story_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "kind": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "body": {
            "type": "string"
          },
          "gist": {
            "type": "string"
          },
          "keys": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "about": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "importance": {
            "type": "number"
          },
          "emotion": {
            "type": "number"
          },
          "strength": {
            "type": "number"
          },
          "status": {
            "type": "string",
            "enum": [
              "active",
              "done",
              "deleted",
              "merged"
            ]
          },
          "evidence": {
            "type": "object",
            "properties": {
              "quote": {
                "type": "string"
              }
            }
          },
          "seq_from": {
            "type": "integer"
          },
          "seq_to": {
            "type": "integer"
          },
          "created_at": {
            "type": "string"
          },
          "score": {
            "type": "number",
            "description": "Only in recall order"
          }
        }
      },
      "Story": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "external_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "title": {
            "type": "string"
          },
          "player": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "description": {
                "type": "string"
              }
            }
          },
          "events": {
            "type": "integer",
            "description": "How many"
          },
          "characters": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "origin": {
                  "type": "string"
                },
                "learned_seq": {
                  "type": "integer"
                },
                "unlearned": {
                  "type": "integer"
                }
              }
            }
          },
          "status": {
            "type": "object",
            "properties": {}
          },
          "learning": {
            "type": "boolean"
          },
          "created_at": {
            "type": "string"
          },
          "updated_at": {
            "type": "string"
          },
          "existing": {
            "type": "boolean",
            "description": "Set when create found this story by external_id"
          }
        }
      },
      "StoryInput": {
        "type": "object",
        "properties": {
          "external_id": {
            "type": "string",
            "description": "Your own id (a conversation id): creating again with it gives the same story back"
          },
          "title": {
            "type": "string"
          },
          "player": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "description": {
                "type": "string",
                "description": "For your narrator only; characters never receive it"
              }
            }
          },
          "characters": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Our ids, your ids or names"
          }
        }
      },
      "EventInput": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Your message id"
          },
          "role": {
            "type": "string",
            "enum": [
              "player",
              "character",
              "narrator"
            ]
          },
          "speaker": {
            "type": "string"
          },
          "text": {
            "type": "string"
          },
          "present": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "Everyone physically there. A story with one character: both are, unless you say otherwise"
          },
          "scene": {
            "type": "string"
          }
        },
        "required": [
          "text"
        ]
      },
      "Event": {
        "type": "object",
        "properties": {
          "seq": {
            "type": "integer"
          },
          "id": {
            "type": [
              "string",
              "null"
            ]
          },
          "role": {
            "type": "string"
          },
          "speaker": {
            "type": "string"
          },
          "text": {
            "type": "string"
          },
          "present": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "scene": {
            "type": "string"
          },
          "inferred": {
            "type": "boolean"
          },
          "created_at": {
            "type": "string"
          }
        }
      },
      "ChatMessage": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Your message id: with it, edits and rerolls are recognized exactly"
          },
          "role": {
            "type": "string",
            "description": "user, assistant, system (skipped), or player / character / narrator"
          },
          "content": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "type": {
                      "type": "string"
                    },
                    "text": {
                      "type": "string"
                    }
                  }
                }
              }
            ]
          },
          "name": {
            "type": "string",
            "description": "Who speaks, for an assistant message voicing one character"
          },
          "present": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "role",
          "content"
        ]
      },
      "SyncResult": {
        "type": "object",
        "properties": {
          "added": {
            "type": "integer"
          },
          "kept": {
            "type": "integer"
          },
          "rewound_from": {
            "type": [
              "integer",
              "null"
            ]
          },
          "from": {
            "type": "integer"
          },
          "to": {
            "type": "integer"
          },
          "learning": {
            "type": "boolean"
          }
        }
      },
      "CharacterContext": {
        "type": "object",
        "properties": {
          "character": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "name": {
                "type": "string"
              },
              "pronouns": {
                "type": "string"
              }
            }
          },
          "text": {
            "type": "string",
            "description": "Put this in the prompt of whoever voices the character"
          },
          "memories": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Memory"
            }
          },
          "relations": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {}
            }
          },
          "state": {
            "type": "object",
            "properties": {
              "mood": {
                "type": "string"
              },
              "on_mind": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "wants": {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            }
          },
          "facts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {}
            }
          },
          "forgot": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "intentions": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "mind": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {}
            }
          }
        }
      },
      "ContextOptions": {
        "type": "object",
        "properties": {
          "characters": {
            "description": "Ids or names (default: everyone in the story), or \"scene\"",
            "oneOf": [
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              {
                "type": "string",
                "enum": [
                  "scene"
                ]
              }
            ]
          },
          "max_characters": {
            "type": "integer",
            "description": "With \"scene\" (default 4, up to 20)"
          },
          "query": {
            "type": "string",
            "description": "The moment, in words, instead of messages"
          },
          "budget": {
            "type": "integer",
            "description": "Max characters of text per character (default 6000)"
          },
          "limit": {
            "type": "integer",
            "description": "Memories to recall (default 10)"
          },
          "place": {
            "type": "boolean",
            "description": "Work out who is where in events nobody placed yet (one small model call)"
          }
        }
      },
      "TurnInput": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ContextOptions"
          },
          {
            "type": "object",
            "properties": {
              "story": {
                "description": "Our id or yours, or a StoryInput with external_id to make it on the first call",
                "oneOf": [
                  {
                    "type": "string"
                  },
                  {
                    "$ref": "#/components/schemas/StoryInput"
                  }
                ]
              },
              "messages": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ChatMessage"
                },
                "description": "Your recent messages as they are now, oldest first (the last 20-50 is plenty)"
              }
            },
            "required": [
              "story",
              "messages"
            ]
          }
        ]
      },
      "TurnResult": {
        "type": "object",
        "properties": {
          "story": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string"
              },
              "external_id": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "created": {
                "type": "boolean"
              }
            }
          },
          "synced": {
            "$ref": "#/components/schemas/SyncResult"
          },
          "characters": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/CharacterContext"
            }
          },
          "check_recommended": {
            "type": "boolean",
            "description": "The player brought up the past: worth a check before the reply is shown"
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "CheckInput": {
        "type": "object",
        "properties": {
          "draft": {
            "type": "string"
          },
          "characters": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "speaker": {
            "type": "string",
            "description": "For a draft without \"Name:\" lines"
          },
          "place": {
            "type": "boolean"
          }
        },
        "required": [
          "draft"
        ]
      },
      "CheckResult": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean"
          },
          "issues": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "character": {
                  "type": "string"
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "leak",
                    "contradiction",
                    "invented_past",
                    "unsupported"
                  ]
                },
                "quote": {
                  "type": "string"
                },
                "why": {
                  "type": "string"
                }
              }
            }
          },
          "fixed": {
            "type": "string",
            "description": "The draft with only the problem lines changed"
          },
          "checked": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "warnings": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        }
      },
      "LearnResult": {
        "type": "object",
        "properties": {
          "learned": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "character": {
                  "type": "string"
                },
                "events": {
                  "type": "integer"
                },
                "written": {
                  "type": "integer"
                },
                "dropped": {
                  "type": "object",
                  "properties": {}
                },
                "error": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    }
  }
}
