{
 "openapi": "3.1.0",
 "info": {
  "title": "Robotext API",
  "version": "1.0.0",
  "summary": "Генерация контента нейросетями: тексты, изображения, презентации, песни, видео",
  "description": "Все запросы, создающие задачу, требуют заголовок Authorization: Bearer <токен>. Токен выдаётся на странице /api после активации PRO.\n\nЧасть сервисов синхронные (генерация текста, анализ и редактирование фото), часть асинхронные: создание задачи возвращает job_id, результат забирается через соответствующий ping-эндпоинт.\n\nОграничения: одновременно выполняется только одна задача (очереди на стороне сервиса нет); статус опрашивается не чаще одного раза в секунду. Почти все ошибки отдаются с HTTP 200 и телом {\"status\": \"error\", ...} — ориентируйтесь на поле status, а не на HTTP-код.\n\nПолная документация: https://robotext.io/llms-full.txt",
  "contact": {
   "url": "https://robotext.io/contact"
  }
 },
 "servers": [
  {
   "url": "https://robotext.io"
  }
 ],
 "security": [
  {
   "BearerAuth": []
  }
 ],
 "tags": [
  {
   "name": "Служебные"
  },
  {
   "name": "Перефразирование"
  },
  {
   "name": "Сокращение"
  },
  {
   "name": "Генерация текста"
  },
  {
   "name": "Изображения"
  },
  {
   "name": "Редактирование фото"
  },
  {
   "name": "Анализ фото"
  },
  {
   "name": "Презентации"
  },
  {
   "name": "Песни"
  },
  {
   "name": "Видео"
  }
 ],
 "paths": {
  "/balance": {
   "get": {
    "summary": "Остаток баланса",
    "description": "Остаток в единицах каждого сервиса. Баланс единый, считается в символах.",
    "tags": [
     "Служебные"
    ],
    "security": [
     {
      "BearerAuth": []
     }
    ],
    "responses": {
     "200": {
      "description": "Успех",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "balance_text": {
           "type": "integer"
          },
          "balance_image": {
           "type": "integer"
          },
          "balance_ocr": {
           "type": "integer"
          },
          "balance_imgedit": {
           "type": "integer"
          },
          "balance_presentation": {
           "type": "integer"
          },
          "balance_song": {
           "type": "integer"
          },
          "balance_video": {
           "type": "integer"
          }
         }
        }
       }
      }
     },
     "default": {
      "description": "Ошибка (обычно с HTTP 200)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/jobs-list": {
   "get": {
    "summary": "История задач по всем сервисам",
    "tags": [
     "Служебные"
    ],
    "security": [
     {
      "BearerAuth": []
     }
    ],
    "responses": {
     "200": {
      "description": "Успех",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "additionalProperties": {
          "type": "array",
          "items": {
           "type": "object"
          }
         }
        }
       }
      }
     },
     "default": {
      "description": "Ошибка (обычно с HTTP 200)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/create-rewrite-job": {
   "post": {
    "summary": "Создать задачу перефразирования",
    "description": "ВАЖНО: токен учитывается только вместе с api=1. Без этого параметра заголовок Authorization игнорируется и запрос выполняется как анонимный.",
    "tags": [
     "Перефразирование"
    ],
    "security": [
     {
      "BearerAuth": []
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/x-www-form-urlencoded": {
       "schema": {
        "type": "object",
        "properties": {
         "api": {
          "type": "string",
          "enum": [
           "1"
          ],
          "description": "Обязательно для работы по токену"
         },
         "mode": {
          "type": "string",
          "enum": [
           "simple",
           "deep"
          ]
         },
         "html": {
          "type": "string",
          "description": "Текст или HTML для обработки"
         },
         "stop_words": {
          "type": "string",
          "description": "JSON-массив строкой"
         }
        },
        "required": [
         "api",
         "mode",
         "html"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Успех",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Задача принята. status=completed здесь означает «принято», а не «готово»: результат забирается через ping-эндпоинт.",
         "properties": {
          "status": {
           "type": "string",
           "enum": [
            "completed"
           ]
          },
          "message": {
           "type": "string"
          },
          "job_id": {
           "type": "string",
           "format": "uuid"
          }
         },
         "required": [
          "status",
          "job_id"
         ]
        }
       }
      }
     },
     "default": {
      "description": "Ошибка (обычно с HTTP 200)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/ping-rewrite-job": {
   "get": {
    "summary": "Статус и результат перефразирования",
    "description": "Опрашивать не чаще одного раза в секунду.",
    "tags": [
     "Перефразирование"
    ],
    "security": [],
    "parameters": [
     {
      "name": "job_id",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Успех",
      "content": {
       "application/json": {
        "schema": {
         "oneOf": [
          {
           "type": "object",
           "properties": {
            "status": {
             "type": "string",
             "enum": [
              "continue"
             ]
            },
            "progress": {
             "type": "string",
             "description": "Текст с HTML; проценты — в notice.progress"
            },
            "notice": {
             "type": "object"
            }
           }
          },
          {
           "type": "object",
           "properties": {
            "status": {
             "type": "string",
             "enum": [
              "completed"
             ]
            },
            "result_text": {
             "type": "array",
             "items": {
              "type": "string"
             },
             "description": "Варианты перефразированного текста"
            },
            "sentences_variat": {
             "type": "object"
            },
            "result_len": {
             "type": "integer",
             "description": "Длина исходного текста = списано символов"
            },
            "balance_message": {
             "type": "string"
            }
           }
          }
         ]
        }
       }
      }
     },
     "default": {
      "description": "Ошибка (обычно с HTTP 200)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/create-reduction-job": {
   "post": {
    "summary": "Создать задачу сокращения",
    "tags": [
     "Сокращение"
    ],
    "security": [
     {
      "BearerAuth": []
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/x-www-form-urlencoded": {
       "schema": {
        "type": "object",
        "properties": {
         "text": {
          "type": "string",
          "minLength": 400,
          "maxLength": 24000
         },
         "requiredLength": {
          "type": "string",
          "description": "Желаемая длина. 400–3000 симв. входа → 200..50% длины; 3000–6000 → 200..1500; 6000+ → 400..3000"
         },
         "mode": {
          "type": "string",
          "enum": [
           "whole"
          ],
          "default": "whole"
         },
         "output_format": {
          "type": "string",
          "enum": [
           "plain",
           "bullet"
          ],
          "default": "plain"
         }
        },
        "required": [
         "text",
         "requiredLength"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Успех",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Задача принята. status=completed здесь означает «принято», а не «готово»: результат забирается через ping-эндпоинт.",
         "properties": {
          "status": {
           "type": "string",
           "enum": [
            "completed"
           ]
          },
          "message": {
           "type": "string"
          },
          "job_id": {
           "type": "string",
           "format": "uuid"
          }
         },
         "required": [
          "status",
          "job_id"
         ]
        }
       }
      }
     },
     "default": {
      "description": "Ошибка (обычно с HTTP 200)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/ping-reduction-job": {
   "get": {
    "summary": "Статус и результат сокращения",
    "tags": [
     "Сокращение"
    ],
    "security": [],
    "parameters": [
     {
      "name": "job_id",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Успех",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "status": {
           "type": "string",
           "enum": [
            "continue",
            "completed"
           ]
          },
          "result_text": {
           "type": "string"
          },
          "balance_message": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "default": {
      "description": "Ошибка (обычно с HTTP 200)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/create-write-sync/{action}": {
   "post": {
    "summary": "Синхронная генерация текста",
    "description": "Готовый текст в поле data. Параметр is_stream=0 читается только из form-данных: при JSON-теле ответ придёт потоком. Шаблоны poem и song-text здесь недоступны (404) — для них асинхронный метод. Состав остальных параметров зависит от шаблона, см. документацию.",
    "tags": [
     "Генерация текста"
    ],
    "security": [
     {
      "BearerAuth": []
     }
    ],
    "parameters": [
     {
      "name": "action",
      "in": "path",
      "required": true,
      "description": "Идентификатор шаблона генерации",
      "schema": {
       "type": "string",
       "enum": [
        "annotation",
        "business-plan",
        "character-history",
        "commercial-offer",
        "complaint",
        "composition",
        "congratulation",
        "content-plan",
        "continue-text",
        "create-dialogue",
        "create-post",
        "create-questions",
        "email",
        "essay",
        "expand-text",
        "fanfiction",
        "html-description",
        "html-keywords",
        "idea",
        "intro",
        "keywords",
        "marketing-plan",
        "naming",
        "nickname",
        "paper",
        "phrase-generator",
        "poem",
        "poem-idea",
        "post-header",
        "post-plan",
        "product-description",
        "product-review",
        "quiz",
        "quote",
        "scenario",
        "seo-text",
        "slogan",
        "song-idea",
        "song-rap",
        "song-text",
        "story",
        "synonymizer",
        "team-name",
        "text-generator"
       ]
      }
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/x-www-form-urlencoded": {
       "schema": {
        "type": "object",
        "properties": {
         "is_stream": {
          "type": "string",
          "enum": [
           "0"
          ],
          "description": "Для API всегда 0"
         },
         "text": {
          "type": "string",
          "description": "Основной параметр большинства шаблонов"
         }
        },
        "required": [
         "is_stream"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Успех",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "status": {
           "type": "string",
           "enum": [
            "completed"
           ]
          },
          "data": {
           "type": "string",
           "description": "Сгенерированный текст"
          },
          "job_id": {
           "type": "string",
           "format": "uuid"
          },
          "balance": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "default": {
      "description": "Ошибка (обычно с HTTP 200)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/create-write-job/{action}": {
   "post": {
    "summary": "Асинхронная генерация текста",
    "description": "Единственный способ для шаблонов poem и song-text.",
    "tags": [
     "Генерация текста"
    ],
    "security": [
     {
      "BearerAuth": []
     }
    ],
    "parameters": [
     {
      "name": "action",
      "in": "path",
      "required": true,
      "description": "Идентификатор шаблона генерации",
      "schema": {
       "type": "string",
       "enum": [
        "annotation",
        "business-plan",
        "character-history",
        "commercial-offer",
        "complaint",
        "composition",
        "congratulation",
        "content-plan",
        "continue-text",
        "create-dialogue",
        "create-post",
        "create-questions",
        "email",
        "essay",
        "expand-text",
        "fanfiction",
        "html-description",
        "html-keywords",
        "idea",
        "intro",
        "keywords",
        "marketing-plan",
        "naming",
        "nickname",
        "paper",
        "phrase-generator",
        "poem",
        "poem-idea",
        "post-header",
        "post-plan",
        "product-description",
        "product-review",
        "quiz",
        "quote",
        "scenario",
        "seo-text",
        "slogan",
        "song-idea",
        "song-rap",
        "song-text",
        "story",
        "synonymizer",
        "team-name",
        "text-generator"
       ]
      }
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/x-www-form-urlencoded": {
       "schema": {
        "type": "object",
        "properties": {
         "text": {
          "type": "string"
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Успех",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Задача принята. status=completed здесь означает «принято», а не «готово»: результат забирается через ping-эндпоинт.",
         "properties": {
          "status": {
           "type": "string",
           "enum": [
            "completed"
           ]
          },
          "message": {
           "type": "string"
          },
          "job_id": {
           "type": "string",
           "format": "uuid"
          }
         },
         "required": [
          "status",
          "job_id"
         ]
        }
       }
      }
     },
     "default": {
      "description": "Ошибка (обычно с HTTP 200)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/ping-write-job": {
   "get": {
    "summary": "Статус и результат генерации текста",
    "description": "Текст приходит в поле result (в синхронном методе — в data).",
    "tags": [
     "Генерация текста"
    ],
    "security": [],
    "parameters": [
     {
      "name": "job_id",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Успех",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "status": {
           "type": "string",
           "enum": [
            "continue",
            "completed"
           ]
          },
          "result": {
           "type": "string"
          },
          "result_len": {
           "type": "integer"
          },
          "balance": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "default": {
      "description": "Ошибка (обычно с HTTP 200)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/create-image-job": {
   "post": {
    "summary": "Создать задачу генерации изображения",
    "tags": [
     "Изображения"
    ],
    "security": [
     {
      "BearerAuth": []
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/x-www-form-urlencoded": {
       "schema": {
        "type": "object",
        "properties": {
         "text": {
          "type": "string",
          "minLength": 4,
          "maxLength": 900
         },
         "aspect": {
          "type": "string",
          "enum": [
           "1x1",
           "9x21",
           "9x16",
           "2x3",
           "3x4",
           "7x9",
           "21x9",
           "16x9",
           "3x2",
           "4x3",
           "9x7"
          ],
          "default": "1x1"
         },
         "style": {
          "type": "string",
          "enum": [
           "nostyle",
           "misc-anime",
           "vector",
           "game-gta",
           "photo-hdr",
           "artstyle-abstract",
           "artstyle-abstract_expressionism",
           "artstyle-art_deco",
           "artstyle-art_nouveau",
           "artstyle-constructivist",
           "artstyle-cubist",
           "artstyle-expressionist",
           "artstyle-graffiti",
           "artstyle-hyperrealism",
           "artstyle-impressionist",
           "artstyle-pixelart",
           "artstyle-pointillism",
           "artstyle-pop_art",
           "artstyle-psychedelic",
           "artstyle-renaissance",
           "artstyle-steampunk",
           "artstyle-surrealist",
           "artstyle-typography",
           "artstyle-watercolor",
           "photo-alien",
           "photo-analog_film",
           "photo-film_noir",
           "photo-glamour",
           "photo-iphone_photographic",
           "photo-long_exposure",
           "photo-neon_noir",
           "photo-silhouette",
           "photo-tilt-shift",
           "misc-3d",
           "misc-architectural",
           "misc-disco",
           "misc-dreamscape",
           "misc-dystopian",
           "misc-fairy_tale",
           "misc-gothic",
           "misc-grunge",
           "misc-horror",
           "misc-kawaii",
           "misc-lovecraftian",
           "misc-macabre",
           "misc-manga",
           "misc-metropolis",
           "misc-minimalist",
           "misc-monochrome",
           "misc-nautical",
           "misc-space",
           "misc-stained_glass",
           "misc-techwear_fashion",
           "misc-tribal",
           "misc-zentangle",
           "game-warhammer40",
           "game-fortnite",
           "game-bubble_bobble",
           "game-cyberpunk_game",
           "game-fighting_game",
           "game-mario",
           "game-minecraft",
           "game-pokemon",
           "game-retro_arcade",
           "game-retro_game",
           "game-rpg_fantasy_game",
           "game-strategy_game",
           "game-streetfighter",
           "game-zelda",
           "ads-advertising",
           "ads-automotive",
           "ads-corporate",
           "ads-fashion_editorial",
           "ads-food_photography",
           "ads-gourmet_food_photography",
           "ads-luxury",
           "ads-real_estate",
           "ads-retail",
           "futuristic-biomechanical",
           "futuristic-biomechanical_cyberpunk",
           "futuristic-cybernetic",
           "futuristic-cybernetic_robot",
           "futuristic-cyberpunk_cityscape",
           "futuristic-futuristic",
           "futuristic-retro_cyberpunk",
           "futuristic-retro_futurism",
           "futuristic-sci-fi",
           "futuristic-vaporwave",
           "papercraft-collage",
           "papercraft-flat_papercut",
           "papercraft-kirigami",
           "papercraft-paper_mache",
           "papercraft-paper_quilling",
           "papercraft-papercut_collage",
           "papercraft-papercut_shadow box",
           "papercraft-stacked_papercut",
           "papercraft-thick_layered_papercut"
          ],
          "default": "nostyle"
         }
        },
        "required": [
         "text"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Успех",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Задача принята. status=completed здесь означает «принято», а не «готово»: результат забирается через ping-эндпоинт.",
         "properties": {
          "status": {
           "type": "string",
           "enum": [
            "completed"
           ]
          },
          "message": {
           "type": "string"
          },
          "job_id": {
           "type": "string",
           "format": "uuid"
          }
         },
         "required": [
          "status",
          "job_id"
         ]
        }
       }
      }
     },
     "default": {
      "description": "Ошибка (обычно с HTTP 200)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/ping-image-job": {
   "get": {
    "summary": "Статус и результат генерации изображения",
    "tags": [
     "Изображения"
    ],
    "security": [],
    "parameters": [
     {
      "name": "job_id",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Успех",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "status": {
           "type": "string",
           "enum": [
            "continue",
            "completed"
           ]
          },
          "result": {
           "type": "string",
           "description": "Идентификатор изображения = job_id"
          },
          "balance": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "default": {
      "description": "Ошибка (обычно с HTTP 200)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/im/{job_id}.png": {
   "get": {
    "summary": "Скачать изображение",
    "description": "Требует токен: изображения недоступны по прямой ссылке.",
    "tags": [
     "Изображения"
    ],
    "security": [
     {
      "BearerAuth": []
     }
    ],
    "parameters": [
     {
      "name": "job_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Байты изображения",
      "content": {
       "image/png": {
        "schema": {
         "type": "string",
         "format": "binary"
        }
       }
      }
     },
     "default": {
      "description": "Ошибка (обычно с HTTP 200)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/image-edit/process": {
   "post": {
    "summary": "Обработать фото (синхронно)",
    "description": "Ответ приходит сразу, до 2 минут. В ответе с токеном есть image_url. Набор параметров зависит от инструмента: background — только для udalit-fon-tovara, scale — только для uvelichit-razreshenie.",
    "tags": [
     "Редактирование фото"
    ],
    "security": [
     {
      "BearerAuth": []
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "multipart/form-data": {
       "schema": {
        "type": "object",
        "properties": {
         "page": {
          "type": "string",
          "enum": [
           "ai-avatar",
           "avatar-dlya-profilya",
           "biznes-portret",
           "dizayn-detskoy",
           "dizayn-fasada",
           "dizayn-interera",
           "dizayn-kuhni",
           "dizayn-remonta",
           "dizayn-spalni",
           "dizayn-vannoy",
           "foto-na-dokumenty",
           "foto-na-rezyume",
           "foto-tovara-ozon",
           "foto-tovara-wildberries",
           "foto-v-multik",
           "foto-v-risunok",
           "foto-v-stile-anime",
           "kollazh-iz-foto",
           "kolorizatsiya-foto",
           "obedinit-dva-foto",
           "odezhda-na-ai-model",
           "otredaktirovat-foto",
           "portret-pitomtsa",
           "primerit-odezhdu",
           "primerit-prichesku",
           "rasshirit-foto",
           "restavratsiya-foto",
           "retush-portreta",
           "semeynyy-portret",
           "sharzh-iz-foto",
           "sovmestnoe-foto",
           "ubrat-vodyanoy-znak",
           "udalit-cheloveka-s-foto",
           "udalit-fon-tovara",
           "udalit-obekt-s-foto",
           "udalit-tekst-s-foto",
           "uluchshit-kachestvo-foto",
           "uvelichit-razreshenie",
           "virtualnyy-steydzhing",
           "vozrastnoy-filtr",
           "zamena-fona-tovara",
           "zamena-litsa"
          ]
         },
         "images": {
          "type": "array",
          "items": {
           "type": "string",
           "format": "binary"
          },
          "description": "До 3 файлов; для удаления фона и апскейла — ровно 1"
         },
         "main": {
          "type": "integer",
          "default": 0
         },
         "query": {
          "type": "string",
          "description": "Свой запрос на русском"
         },
         "resolution": {
          "type": "string",
          "default": "source",
          "description": "source | ключ формата (1x1, 16x9, …) | WxH (16..1536)"
         },
         "background": {
          "type": "string",
          "enum": [
           "transparent",
           "white"
          ],
          "default": "transparent"
         },
         "scale": {
          "type": "string",
          "enum": [
           "2",
           "4"
          ],
          "default": "2"
         }
        },
        "required": [
         "page",
         "images"
        ]
       },
       "encoding": {
        "images": {
         "contentType": "image/*"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Успех",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "status": {
           "type": "string",
           "enum": [
            "completed"
           ]
          },
          "job_id": {
           "type": "string",
           "format": "uuid"
          },
          "image_url": {
           "type": "string",
           "format": "uri"
          },
          "balance": {
           "type": "integer"
          }
         }
        }
       }
      }
     },
     "default": {
      "description": "Ошибка (обычно с HTTP 200)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/ime/{job_id}.png": {
   "get": {
    "summary": "Скачать обработанное фото",
    "tags": [
     "Редактирование фото"
    ],
    "security": [
     {
      "BearerAuth": []
     }
    ],
    "parameters": [
     {
      "name": "job_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Байты изображения",
      "content": {
       "image/png": {
        "schema": {
         "type": "string",
         "format": "binary"
        }
       }
      }
     },
     "default": {
      "description": "Ошибка (обычно с HTTP 200)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/ocr/process": {
   "post": {
    "summary": "Проанализировать фото (синхронно)",
    "description": "С токеном стриминг выключается, ответ приходит одним JSON.",
    "tags": [
     "Анализ фото"
    ],
    "security": [
     {
      "BearerAuth": []
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "multipart/form-data": {
       "schema": {
        "type": "object",
        "properties": {
         "image": {
          "type": "string",
          "format": "binary",
          "description": "До 15 МБ, до 10000×10000"
         },
         "page": {
          "type": "string",
          "enum": [
           "nayti-mesto-po-foto",
           "opisat-izobrazhenie",
           "opisat-vneshnost-cheloveka",
           "opredelit-bolezn-rasteniya",
           "opredelit-obekt-na-foto",
           "opredelit-porodu-po-foto",
           "opredelit-pticu-po-foto",
           "opredelit-rastenie-po-foto",
           "opredelit-shrift-po-foto",
           "opredelit-tip-lica-po-foto",
           "opredelit-zhivotnoe-po-foto",
           "perevesti-tekst-s-foto",
           "proanalizirovat-izobrazhenie",
           "raspoznat-rukopisnyy-tekst",
           "raspoznat-tekst-s-foto",
           "reshit-zadachu-po-foto"
          ]
         },
         "query": {
          "type": "string",
          "minLength": 10,
          "maxLength": 300,
          "description": "Свой запрос; без него берётся стандартный запрос подсервиса"
         }
        },
        "required": [
         "image",
         "page"
        ]
       },
       "encoding": {
        "image": {
         "contentType": "image/*"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Успех",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "status": {
           "type": "string",
           "enum": [
            "completed"
           ]
          },
          "text": {
           "type": "string",
           "description": "Ответ модели"
          },
          "job_id": {
           "type": "string",
           "format": "uuid"
          },
          "balance": {
           "type": "integer"
          }
         }
        }
       }
      }
     },
     "default": {
      "description": "Ошибка (обычно с HTTP 200)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/create-presentation-job": {
   "post": {
    "summary": "Создать задачу генерации презентации",
    "description": "Нужно передать topic или text — хотя бы одно из двух.",
    "tags": [
     "Презентации"
    ],
    "security": [
     {
      "BearerAuth": []
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/x-www-form-urlencoded": {
       "schema": {
        "type": "object",
        "properties": {
         "topic": {
          "type": "string",
          "maxLength": 300
         },
         "text": {
          "type": "string",
          "maxLength": 24000
         },
         "slide_count": {
          "type": "string",
          "enum": [
           "10",
           "15",
           "20"
          ]
         },
         "template": {
          "type": "string",
          "enum": [
           "basic",
           "organic",
           "color",
           "modern",
           "black",
           "plain"
          ]
         }
        },
        "required": [
         "slide_count",
         "template"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Успех",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Задача принята. status=completed здесь означает «принято», а не «готово»: результат забирается через ping-эндпоинт.",
         "properties": {
          "status": {
           "type": "string",
           "enum": [
            "completed"
           ]
          },
          "message": {
           "type": "string"
          },
          "job_id": {
           "type": "string",
           "format": "uuid"
          }
         },
         "required": [
          "status",
          "job_id"
         ]
        }
       }
      }
     },
     "default": {
      "description": "Ошибка (обычно с HTTP 200)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/ping-presentation-job": {
   "get": {
    "summary": "Статус и результат генерации презентации",
    "tags": [
     "Презентации"
    ],
    "security": [],
    "parameters": [
     {
      "name": "job_id",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Успех",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "status": {
           "type": "string",
           "enum": [
            "continue",
            "completed"
           ]
          },
          "progress": {
           "type": "integer"
          },
          "result": {
           "type": "object",
           "properties": {
            "job_id": {
             "type": "string"
            },
            "title": {
             "type": "string"
            }
           }
          },
          "balance": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "default": {
      "description": "Ошибка (обычно с HTTP 200)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/download-presentation": {
   "get": {
    "summary": "Скачать презентацию",
    "tags": [
     "Презентации"
    ],
    "security": [
     {
      "BearerAuth": []
     }
    ],
    "parameters": [
     {
      "name": "job_id",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      }
     },
     {
      "name": "format",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "enum": [
        "pptx",
        "pdf"
       ],
       "default": "pdf"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Файл презентации",
      "content": {
       "application/octet-stream": {
        "schema": {
         "type": "string",
         "format": "binary"
        }
       }
      }
     },
     "default": {
      "description": "Ошибка (обычно с HTTP 200)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/create-song-job": {
   "post": {
    "summary": "Создать задачу генерации песни",
    "tags": [
     "Песни"
    ],
    "security": [
     {
      "BearerAuth": []
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "application/x-www-form-urlencoded": {
       "schema": {
        "type": "object",
        "properties": {
         "preset_style": {
          "type": "string",
          "enum": [
           "__custom__",
           "Поп",
           "K-pop",
           "Романтическая",
           "Народная",
           "Военно-патриотическая",
           "Шансон",
           "Детская",
           "Хип-хоп / Рэп",
           "Трэп",
           "Дрилл",
           "Фонк",
           "Рок",
           "Альтернативный рок",
           "Панк",
           "Металл",
           "R&B",
           "Соул",
           "Регги",
           "Реггетон",
           "EDM",
           "Диско",
           "Хаус",
           "Техно",
           "Drum & Bass"
          ],
          "description": "__custom__ — стиль берётся из поля genre"
         },
         "genre": {
          "type": "string",
          "maxLength": 250
         },
         "title": {
          "type": "string",
          "maxLength": 50,
          "description": "Необязательно: если не передано, название придумает нейросеть по тексту (для инструментала — по стилю)"
         },
         "text": {
          "type": "string",
          "minLength": 10,
          "maxLength": 2500,
          "description": "Текст с тегами секций [Verse]/[Chorus]/[Bridge]; не требуется при vocals=none"
         },
         "vocals": {
          "type": "string",
          "enum": [
           "male",
           "female",
           "random",
           "none"
          ]
         },
         "time_period": {
          "type": "integer",
          "deprecated": true,
          "description": "Устарел, принимается для совместимости и не влияет на результат: длительность выбирает модель по объёму текста"
         },
         "format_file": {
          "type": "string",
          "enum": [
           "mp3",
           "wav"
          ],
          "default": "mp3"
         }
        },
        "required": [
         "preset_style",
         "genre",
         "vocals"
        ]
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Успех",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Задача принята. status=completed здесь означает «принято», а не «готово»: результат забирается через ping-эндпоинт.",
         "properties": {
          "status": {
           "type": "string",
           "enum": [
            "completed"
           ]
          },
          "message": {
           "type": "string"
          },
          "job_id": {
           "type": "string",
           "format": "uuid"
          }
         },
         "required": [
          "status",
          "job_id"
         ]
        }
       }
      }
     },
     "default": {
      "description": "Ошибка (обычно с HTTP 200)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/ping-song-job": {
   "get": {
    "summary": "Статус и результат генерации песни",
    "tags": [
     "Песни"
    ],
    "security": [],
    "parameters": [
     {
      "name": "job_id",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Успех",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "status": {
           "type": "string",
           "enum": [
            "continue",
            "completed"
           ]
          },
          "progress": {
           "type": "integer"
          },
          "result": {
           "type": "object",
           "properties": {
            "job_id": {
             "type": "string"
            },
            "title": {
             "type": "string"
            },
            "audio_data": {
             "type": "string",
             "format": "uri",
             "description": "Подписанная ссылка, действует 1 час"
            },
            "video_data": {
             "type": "string",
             "format": "uri"
            }
           }
          },
          "balance": {
           "type": "string"
          },
          "stage": {
           "type": "string",
           "enum": [
            "prepare",
            "generate",
            "save"
           ]
          },
          "eta_seconds": {
           "type": "number",
           "description": "Ожидаемая полная длительность задачи, с"
          },
          "elapsed_seconds": {
           "type": "number",
           "description": "Сколько секунд задача уже выполняется"
          }
         }
        }
       }
      }
     },
     "default": {
      "description": "Ошибка (обычно с HTTP 200)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/download-song": {
   "get": {
    "summary": "Скачать песню",
    "tags": [
     "Песни"
    ],
    "security": [
     {
      "BearerAuth": []
     }
    ],
    "parameters": [
     {
      "name": "job_id",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      }
     },
     {
      "name": "format",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "enum": [
        "mp3",
        "wav"
       ],
       "default": "mp3"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Аудиофайл",
      "content": {
       "audio/mpeg": {
        "schema": {
         "type": "string",
         "format": "binary"
        }
       }
      }
     },
     "default": {
      "description": "Ошибка (обычно с HTTP 200)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/create-video-job": {
   "post": {
    "summary": "Создать задачу генерации видео",
    "tags": [
     "Видео"
    ],
    "security": [
     {
      "BearerAuth": []
     }
    ],
    "requestBody": {
     "required": true,
     "content": {
      "multipart/form-data": {
       "schema": {
        "type": "object",
        "properties": {
         "query": {
          "type": "string",
          "minLength": 10,
          "maxLength": 20000,
          "description": "Описание сцены на русском"
         },
         "page": {
          "type": "string",
          "enum": [
           "ai-obyatie",
           "ai-poceluy",
           "anime-video-iz-foto",
           "cifrovoy-dvoynik-iz-foto",
           "figurka-i-kukla-iz-foto",
           "foto-v-video",
           "govoryashchee-foto",
           "ii-diktor-v-kadre",
           "kak-ya-budu-vyglyadet-esli-pohudeyu",
           "kak-ya-budu-vyglyadet-v-starosti",
           "kakim-budet-nash-rebenok",
           "memorialnoe-video",
           "omolodit-foto",
           "ozhivit-foto-tovara",
           "ozhivit-risunok",
           "ozhivit-staroe-foto",
           "poyushchee-i-tancuyushchee-foto",
           "prevrashchenie-v-supergeroya",
           "reklamnyy-rolik-dlya-biznesa",
           "sebya-v-stile-videoigry",
           "sovmestnoe-video-iz-dvuh-foto",
           "svadebnoe-video-i-priglashenie",
           "tekst-v-video",
           "ugc-reklama-s-ii-akterom",
           "video-dlya-kartochki-ozon",
           "video-dlya-kartochki-wildberries",
           "video-dlya-reels-shorts-tiktok",
           "video-mezhdu-dvumya-kadrami",
           "video-na-godovshchinu",
           "video-na-vypusknoy",
           "video-na-yubiley",
           "video-po-foto-i-opisaniyu",
           "video-s-pitomcem",
           "video-so-znamenitostyu",
           "video-so-zvukom",
           "video-vizitka",
           "videootkrytka",
           "videopozdravlenie-s-23-fevralya",
           "videopozdravlenie-s-8-marta",
           "videopozdravlenie-s-dnem-rozhdeniya",
           "videopozdravlenie-s-novym-godom"
          ]
         },
         "seconds": {
          "type": "integer",
          "minimum": 4,
          "maximum": 12,
          "default": 4
         },
         "resolution": {
          "type": "string",
          "enum": [
           "16x9",
           "1x1",
           "2x3",
           "3x2",
           "3x4",
           "4x3",
           "7x9",
           "9x16",
           "9x7",
           "auto"
          ],
          "default": "16x9"
         },
         "images": {
          "type": "array",
          "items": {
           "type": "string",
           "format": "binary"
          },
          "description": "Фото для первого кадра, максимум зависит от подсервиса (1–3)"
         },
         "main": {
          "type": "integer",
          "default": 0
         },
         "image_last": {
          "type": "string",
          "format": "binary",
          "description": "Только для подсервиса video-mezhdu-dvumya-kadrami"
         }
        },
        "required": [
         "query"
        ]
       },
       "encoding": {
        "images": {
         "contentType": "image/*"
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Успех",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "description": "Задача принята. status=completed здесь означает «принято», а не «готово»: результат забирается через ping-эндпоинт.",
         "properties": {
          "status": {
           "type": "string",
           "enum": [
            "completed"
           ]
          },
          "message": {
           "type": "string"
          },
          "job_id": {
           "type": "string",
           "format": "uuid"
          }
         },
         "required": [
          "status",
          "job_id"
         ]
        }
       }
      }
     },
     "default": {
      "description": "Ошибка (обычно с HTTP 200)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/ping-video-job": {
   "get": {
    "summary": "Статус и результат генерации видео",
    "tags": [
     "Видео"
    ],
    "security": [
     {
      "BearerAuth": []
     }
    ],
    "parameters": [
     {
      "name": "job_id",
      "in": "query",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Успех",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "properties": {
          "status": {
           "type": "string",
           "enum": [
            "continue",
            "completed"
           ]
          },
          "progress": {
           "type": "integer"
          },
          "result": {
           "type": "object",
           "properties": {
            "job_id": {
             "type": "string"
            },
            "video_url": {
             "type": "string",
             "description": "Относительный путь к ролику"
            },
            "seconds": {
             "type": "integer"
            },
            "width": {
             "type": "integer"
            },
            "height": {
             "type": "integer"
            },
            "seed": {
             "type": "integer"
            },
            "demo": {
             "type": "boolean",
             "description": "true — демо-ролик, скачивание закрыто"
            }
           }
          },
          "balance": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "default": {
      "description": "Ошибка (обычно с HTTP 200)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  },
  "/vid/{job_id}.mp4": {
   "get": {
    "summary": "Скачать или посмотреть видео",
    "description": "Поддерживается заголовок Range. Демо-ролики скачивать нельзя (403).",
    "tags": [
     "Видео"
    ],
    "security": [
     {
      "BearerAuth": []
     }
    ],
    "parameters": [
     {
      "name": "job_id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string",
       "format": "uuid"
      }
     },
     {
      "name": "download",
      "in": "query",
      "required": false,
      "schema": {
       "type": "string",
       "enum": [
        "1"
       ]
      }
     }
    ],
    "responses": {
     "200": {
      "description": "MP4",
      "content": {
       "video/mp4": {
        "schema": {
         "type": "string",
         "format": "binary"
        }
       }
      }
     },
     "403": {
      "description": "Скачивание демо-ролика недоступно"
     },
     "default": {
      "description": "Ошибка (обычно с HTTP 200)",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Error"
        }
       }
      }
     }
    }
   }
  }
 },
 "components": {
  "securitySchemes": {
   "BearerAuth": {
    "type": "http",
    "scheme": "bearer",
    "description": "Токен со страницы /api"
   }
  },
  "schemas": {
   "Error": {
    "type": "object",
    "description": "Ошибка. Отдаётся с HTTP 200 — ориентируйтесь на поле status.",
    "properties": {
     "status": {
      "type": "string",
      "enum": [
       "error"
      ]
     },
     "message": {
      "type": "string",
      "description": "Текст для человека, может содержать HTML"
     },
     "notice": {
      "type": "object",
      "description": "Машиночитаемый вид ошибки",
      "properties": {
       "type": {
        "type": "string",
        "enum": [
         "error",
         "validation",
         "limit",
         "moderation",
         "moderation_block",
         "paywall_balance",
         "paywall_demo",
         "paywall_queue",
         "edit_limit",
         "unavailable"
        ]
       },
       "title": {
        "type": "string"
       },
       "text": {
        "type": "string"
       }
      }
     },
     "error_type": {
      "type": "string",
      "enum": [
       "format",
       "resolution",
       "size",
       "invalid"
      ],
      "description": "Только для ошибок загружаемых файлов"
     }
    },
    "required": [
     "status"
    ]
   },
   "JobCreated": {
    "type": "object",
    "description": "Задача принята. status=completed здесь означает «принято», а не «готово»: результат забирается через ping-эндпоинт.",
    "properties": {
     "status": {
      "type": "string",
      "enum": [
       "completed"
      ]
     },
     "message": {
      "type": "string"
     },
     "job_id": {
      "type": "string",
      "format": "uuid"
     }
    },
    "required": [
     "status",
     "job_id"
    ]
   }
  }
 }
}