{
  "openapi": "3.1.0",
  "jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
  "info": {
    "title": "HopBase API",
    "version": "2026-09-25",
    "description": "OpenAPI description of the HopBase multi-model API gateway: OpenAI-compatible chat, Responses, images and speech; Anthropic Messages; async video; account endpoints. Image request bodies reference a per-model JSON Schema at https://hop-base.com/spec/models/<model>.json, generated from the gateway validation code. Generated by toc-landing/docs-app/scripts/build-openapi.mjs; the docs API reference pages render from the same data."
  },
  "servers": [
    {
      "url": "https://api.hop-base.com"
    }
  ],
  "security": [
    {
      "bearer": []
    }
  ],
  "tags": [
    {
      "name": "Chat"
    },
    {
      "name": "Images"
    },
    {
      "name": "Video"
    },
    {
      "name": "Speech"
    },
    {
      "name": "Account and catalog"
    }
  ],
  "paths": {
    "/v1/chat/completions": {
      "post": {
        "operationId": "createChatCompletion",
        "summary": "Create chat completion",
        "description": "Given a list of messages, returns the model's reply. With the OpenAI SDK, just set the Base URL to `https://api.hop-base.com/v1` and use an API key from the matching group.\n\nThe table lists only the fields the gateway checks, rewrites or rejects, plus values documented on each model page; **OpenAI fields not listed are forwarded as-is**, with ranges per the model's official spec. The whole request body is capped at 60 MB; larger bodies return 413.",
        "tags": [
          "Chat"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "",
                "properties": {
                  "model": {
                    "type": "string",
                    "description": "A model ID in the current key's group; `GET /v1/models` is authoritative. If the group does not include the model, returns 404 `model_not_found`; image models such as `gpt-image-*` return 400 `image models do not support Chat Completions, please use the Images API` on this endpoint"
                  },
                  "messages": {
                    "type": "array",
                    "description": "Conversation messages. Missing returns 400 `missing messages field`; an empty array returns 400 `messages must not be an empty array`",
                    "items": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "role": {
                          "type": "string",
                          "description": "`system` / `user` / `assistant` / `tool`, in OpenAI format"
                        },
                        "content": {
                          "description": "A string, or an array of content parts. Part `{\"type\": \"text\", \"text\": …}`; vision models also accept `{\"type\": \"image_url\", \"image_url\": {\"url\": …}}`. Per-model image requirements are shown under the model picker above",
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "array",
                              "description": "",
                              "items": {
                                "type": "object",
                                "description": "",
                                "properties": {
                                  "type": {
                                    "type": "string",
                                    "description": "`text` or `image_url`"
                                  },
                                  "text": {
                                    "type": "string",
                                    "description": "Text when `type` is `text`"
                                  },
                                  "image_url": {
                                    "type": "object",
                                    "description": "Image when `type` is `image_url`",
                                    "properties": {
                                      "url": {
                                        "type": "string",
                                        "description": "HTTP(S) link or `data:` URI; supported forms vary by model"
                                      }
                                    },
                                    "required": [
                                      "url"
                                    ]
                                  }
                                },
                                "required": [
                                  "type"
                                ]
                              }
                            }
                          ]
                        },
                        "tool_calls": {
                          "type": "array",
                          "description": "`assistant` only: the tool calls returned by the model in the previous turn, sent back unchanged",
                          "items": {
                            "type": "object"
                          }
                        },
                        "tool_call_id": {
                          "type": "string",
                          "description": "`tool` only: must match `tool_calls[].id` from the previous turn"
                        }
                      },
                      "required": [
                        "role"
                      ]
                    },
                    "minItems": 1
                  },
                  "max_tokens": {
                    "type": "integer",
                    "description": "Output cap. The gateway does not truncate or rewrite it; the limit follows the model's official spec, and values above it return an error from the model"
                  },
                  "max_completion_tokens": {
                    "type": "integer",
                    "description": "Same as `max_tokens`; the newer OpenAI field name"
                  },
                  "stream": {
                    "type": "boolean",
                    "description": "`true` returns SSE; see [Streaming events](https://hop-base.com/zh-cn/docs/api-reference/streaming-events) for the event format",
                    "default": false
                  },
                  "stream_options": {
                    "type": "object",
                    "description": "Streaming options",
                    "properties": {
                      "include_usage": {
                        "type": "boolean",
                        "description": "When streaming, pass `true` to receive a final event carrying only `usage` (with empty `choices`); if omitted it is not sent. Billing is unaffected",
                        "default": false
                      }
                    }
                  },
                  "tools": {
                    "type": "array",
                    "description": "Function tools in OpenAI function tools format, forwarded as-is.",
                    "items": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "type": {
                          "const": "function",
                          "description": "Always `function`"
                        },
                        "function": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "name": {
                              "type": "string",
                              "description": "Function name"
                            },
                            "description": {
                              "type": "string",
                              "description": "What the function does; the model uses it to decide whether to call it"
                            },
                            "parameters": {
                              "type": "object",
                              "description": "JSON Schema for the parameters"
                            }
                          },
                          "required": [
                            "name"
                          ]
                        }
                      },
                      "required": [
                        "type",
                        "function"
                      ]
                    }
                  },
                  "tool_choice": {
                    "description": "`auto` / `none` / `required` or a specific function, forwarded as-is",
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "object"
                      }
                    ]
                  },
                  "temperature": {
                    "type": "number",
                    "description": "Sampling temperature, forwarded as-is; range per the model's official spec"
                  },
                  "top_p": {
                    "type": "number",
                    "description": "Nucleus sampling, forwarded as-is; range per the model's official spec"
                  },
                  "reasoning_effort": {
                    "type": "string",
                    "description": "Reasoning effort. Values vary by model; select a model family above to see them"
                  },
                  "service_tier": {
                    "type": "string",
                    "description": "Only `priority` / `flex` are kept; other values are removed before forwarding, without an error",
                    "enum": [
                      "priority",
                      "flex"
                    ]
                  }
                },
                "required": [
                  "model",
                  "messages"
                ],
                "additionalProperties": true
              },
              "examples": {
                "text": {
                  "summary": "Text",
                  "value": {
                    "model": "gpt-5.6-sol",
                    "messages": [
                      {
                        "role": "user",
                        "content": "Hello"
                      }
                    ]
                  }
                },
                "stream": {
                  "summary": "Streaming",
                  "value": {
                    "model": "gpt-5.6-sol",
                    "stream": true,
                    "stream_options": {
                      "include_usage": true
                    },
                    "messages": [
                      {
                        "role": "user",
                        "content": "Introduce yourself in three sentences"
                      }
                    ]
                  }
                },
                "tools": {
                  "summary": "Tool calls",
                  "value": {
                    "model": "gpt-5.6-sol",
                    "messages": [
                      {
                        "role": "user",
                        "content": "What's the weather in Shanghai today?"
                      }
                    ],
                    "tools": [
                      {
                        "type": "function",
                        "function": {
                          "name": "get_weather",
                          "description": "Get the weather for a city",
                          "parameters": {
                            "type": "object",
                            "properties": {
                              "city": {
                                "type": "string"
                              }
                            },
                            "required": [
                              "city"
                            ]
                          }
                        }
                      }
                    ]
                  }
                },
                "image": {
                  "summary": "Image input",
                  "value": {
                    "model": "deepseek-v4.1-flash",
                    "messages": [
                      {
                        "role": "user",
                        "content": [
                          {
                            "type": "text",
                            "text": "What is the main takeaway of this chart?"
                          },
                          {
                            "type": "image_url",
                            "image_url": {
                              "url": "https://example.com/chart.png"
                            }
                          }
                        ]
                      }
                    ]
                  }
                }
              },
              "x-hopbase-variants": [
                {
                  "id": "gpt",
                  "label": "GPT",
                  "doc": "/docs/protocols/openai-sdk",
                  "note": "A key from the \"Codex Plus\" or \"Codex Pro\" group. OpenAI fields not listed are forwarded as-is, with ranges per the model's official spec.",
                  "schema": {
                    "type": "object",
                    "description": "",
                    "properties": {
                      "model": {
                        "type": "string",
                        "description": "A model ID in the current key's group; `GET /v1/models` is authoritative. If the group does not include the model, returns 404 `model_not_found`; image models such as `gpt-image-*` return 400 `image models do not support Chat Completions, please use the Images API` on this endpoint",
                        "enum": [
                          "codex-auto-review",
                          "gpt-5.3-codex-spark",
                          "gpt-5.4",
                          "gpt-5.4-mini",
                          "gpt-5.5",
                          "gpt-5.6-sol",
                          "gpt-5.6-terra",
                          "gpt-6-astra",
                          "gpt-6-luna",
                          "gpt-6-sol"
                        ]
                      },
                      "messages": {
                        "type": "array",
                        "description": "Conversation messages. Missing returns 400 `missing messages field`; an empty array returns 400 `messages must not be an empty array`",
                        "items": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "role": {
                              "type": "string",
                              "description": "`system` / `user` / `assistant` / `tool`, in OpenAI format"
                            },
                            "content": {
                              "description": "A string, or an array of content parts. Part `{\"type\": \"text\", \"text\": …}`; vision models also accept `{\"type\": \"image_url\", \"image_url\": {\"url\": …}}`. Per-model image requirements are shown under the model picker above",
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "array",
                                  "description": "",
                                  "items": {
                                    "type": "object",
                                    "description": "",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "description": "`text` or `image_url`"
                                      },
                                      "text": {
                                        "type": "string",
                                        "description": "Text when `type` is `text`"
                                      },
                                      "image_url": {
                                        "type": "object",
                                        "description": "Image when `type` is `image_url`",
                                        "properties": {
                                          "url": {
                                            "type": "string",
                                            "description": "HTTP(S) link or `data:` URI; supported forms vary by model"
                                          }
                                        },
                                        "required": [
                                          "url"
                                        ]
                                      }
                                    },
                                    "required": [
                                      "type"
                                    ]
                                  }
                                }
                              ]
                            },
                            "tool_calls": {
                              "type": "array",
                              "description": "`assistant` only: the tool calls returned by the model in the previous turn, sent back unchanged",
                              "items": {
                                "type": "object"
                              }
                            },
                            "tool_call_id": {
                              "type": "string",
                              "description": "`tool` only: must match `tool_calls[].id` from the previous turn"
                            }
                          },
                          "required": [
                            "role"
                          ]
                        },
                        "minItems": 1
                      },
                      "max_tokens": {
                        "type": "integer",
                        "description": "Output cap. The gateway does not truncate or rewrite it; the limit follows the model's official spec, and values above it return an error from the model"
                      },
                      "max_completion_tokens": {
                        "type": "integer",
                        "description": "Same as `max_tokens`; the newer OpenAI field name"
                      },
                      "stream": {
                        "type": "boolean",
                        "description": "`true` returns SSE; see [Streaming events](https://hop-base.com/zh-cn/docs/api-reference/streaming-events) for the event format",
                        "default": false
                      },
                      "stream_options": {
                        "type": "object",
                        "description": "Streaming options",
                        "properties": {
                          "include_usage": {
                            "type": "boolean",
                            "description": "When streaming, pass `true` to receive a final event carrying only `usage` (with empty `choices`); if omitted it is not sent. Billing is unaffected",
                            "default": false
                          }
                        }
                      },
                      "tools": {
                        "type": "array",
                        "description": "Function tools in OpenAI function tools format, forwarded as-is.",
                        "items": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "type": {
                              "const": "function",
                              "description": "Always `function`"
                            },
                            "function": {
                              "type": "object",
                              "description": "",
                              "properties": {
                                "name": {
                                  "type": "string",
                                  "description": "Function name"
                                },
                                "description": {
                                  "type": "string",
                                  "description": "What the function does; the model uses it to decide whether to call it"
                                },
                                "parameters": {
                                  "type": "object",
                                  "description": "JSON Schema for the parameters"
                                }
                              },
                              "required": [
                                "name"
                              ]
                            }
                          },
                          "required": [
                            "type",
                            "function"
                          ]
                        }
                      },
                      "tool_choice": {
                        "description": "`auto` / `none` / `required` or a specific function, forwarded as-is",
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "object"
                          }
                        ]
                      },
                      "temperature": {
                        "type": "number",
                        "description": "Sampling temperature, forwarded as-is; range per the model's official spec"
                      },
                      "top_p": {
                        "type": "number",
                        "description": "Nucleus sampling, forwarded as-is; range per the model's official spec"
                      },
                      "reasoning_effort": {
                        "type": "string",
                        "description": "Reasoning effort. Values vary by model; select a model family above to see them"
                      },
                      "service_tier": {
                        "type": "string",
                        "description": "Only `priority` / `flex` are kept; other values are removed before forwarding, without an error",
                        "enum": [
                          "priority",
                          "flex"
                        ]
                      }
                    },
                    "required": [
                      "model",
                      "messages"
                    ],
                    "additionalProperties": true
                  }
                },
                {
                  "id": "gemini",
                  "label": "Gemini",
                  "doc": "/docs/protocols/gemini",
                  "note": "Based on the \"Gemini Official Direct\" group; Chat Completions only, Responses is not supported.",
                  "schema": {
                    "type": "object",
                    "description": "",
                    "properties": {
                      "model": {
                        "type": "string",
                        "description": "A model ID in the current key's group; `GET /v1/models` is authoritative. If the group does not include the model, returns 404 `model_not_found`; image models such as `gpt-image-*` return 400 `image models do not support Chat Completions, please use the Images API` on this endpoint",
                        "enum": [
                          "gemini-2.5-flash",
                          "gemini-2.5-flash-lite",
                          "gemini-2.5-pro",
                          "gemini-3-flash-preview",
                          "gemini-3.1-flash-lite",
                          "gemini-3.1-flash-lite-preview",
                          "gemini-3.1-pro-preview",
                          "gemini-3.1-pro-preview-customtools",
                          "gemini-3.5-flash",
                          "gemini-3.5-flash-lite",
                          "gemini-3.6-flash",
                          "gemini-3.7-flash",
                          "gemini-3.8-flash"
                        ]
                      },
                      "messages": {
                        "type": "array",
                        "description": "Only `text` and `image_url` content parts are read. `image_url` accepts base64 data URLs only (public links return 400 `image_url only supports data URLs (base64-embedded images)`); `input_audio`, `file` and `video_url` are silently dropped; `role: \"tool\"` is sent as user text; no usable content returns 400",
                        "items": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "role": {
                              "type": "string",
                              "description": "`system` / `user` / `assistant` / `tool`, in OpenAI format"
                            },
                            "content": {
                              "description": "A string, or an array of content parts. Part `{\"type\": \"text\", \"text\": …}`; vision models also accept `{\"type\": \"image_url\", \"image_url\": {\"url\": …}}`. Per-model image requirements are shown under the model picker above",
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "array",
                                  "description": "",
                                  "items": {
                                    "type": "object",
                                    "description": "",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "description": "`text` or `image_url`"
                                      },
                                      "text": {
                                        "type": "string",
                                        "description": "Text when `type` is `text`"
                                      },
                                      "image_url": {
                                        "type": "object",
                                        "description": "Image when `type` is `image_url`",
                                        "properties": {
                                          "url": {
                                            "type": "string",
                                            "description": "HTTP(S) link or `data:` URI; supported forms vary by model"
                                          }
                                        },
                                        "required": [
                                          "url"
                                        ]
                                      }
                                    },
                                    "required": [
                                      "type"
                                    ]
                                  }
                                }
                              ]
                            },
                            "tool_calls": {
                              "type": "array",
                              "description": "`assistant` only: the tool calls returned by the model in the previous turn, sent back unchanged",
                              "items": {
                                "type": "object"
                              }
                            },
                            "tool_call_id": {
                              "type": "string",
                              "description": "`tool` only: must match `tool_calls[].id` from the previous turn"
                            }
                          },
                          "required": [
                            "role"
                          ]
                        },
                        "minItems": 1
                      },
                      "max_tokens": {
                        "type": "integer",
                        "description": "If `max_completion_tokens` is also sent, `max_tokens` wins. Thinking tokens count toward this cap; 4096 or more is recommended"
                      },
                      "max_completion_tokens": {
                        "type": "integer",
                        "description": "Same as `max_tokens`; the newer OpenAI field name"
                      },
                      "stream": {
                        "type": "boolean",
                        "description": "`true` returns SSE; see [Streaming events](https://hop-base.com/zh-cn/docs/api-reference/streaming-events) for the event format",
                        "default": false
                      },
                      "stream_options": {
                        "type": "object",
                        "description": "Streaming options",
                        "properties": {
                          "include_usage": {
                            "type": "boolean",
                            "description": "When streaming, pass `true` to receive a final event carrying only `usage` (with empty `choices`); if omitted it is not sent. Billing is unaffected",
                            "default": false
                          }
                        }
                      },
                      "tools": {
                        "type": "array",
                        "description": "Function tools in OpenAI function tools format, forwarded as-is.",
                        "items": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "type": {
                              "const": "function",
                              "description": "Always `function`"
                            },
                            "function": {
                              "type": "object",
                              "description": "",
                              "properties": {
                                "name": {
                                  "type": "string",
                                  "description": "Function name"
                                },
                                "description": {
                                  "type": "string",
                                  "description": "What the function does; the model uses it to decide whether to call it"
                                },
                                "parameters": {
                                  "type": "object",
                                  "description": "JSON Schema for the parameters"
                                }
                              },
                              "required": [
                                "name"
                              ]
                            }
                          },
                          "required": [
                            "type",
                            "function"
                          ]
                        }
                      },
                      "tool_choice": {
                        "description": "`auto` / `none` / `required` or a specific function, forwarded as-is",
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "object"
                          }
                        ]
                      },
                      "temperature": {
                        "type": "number",
                        "description": "Sampling temperature, forwarded as-is; range per the model's official spec"
                      },
                      "top_p": {
                        "type": "number",
                        "description": "Nucleus sampling, forwarded as-is; range per the model's official spec"
                      },
                      "reasoning_effort": {
                        "type": "string",
                        "description": "`none` / `minimal` → thinking budget 0; `medium` → 8192; `high` → 24576; `low` and other values keep the model default",
                        "enum": [
                          "none",
                          "minimal",
                          "low",
                          "medium",
                          "high"
                        ]
                      },
                      "service_tier": {
                        "type": "string",
                        "description": "Only `priority` / `flex` are kept; other values are removed before forwarding, without an error",
                        "enum": [
                          "priority",
                          "flex"
                        ]
                      }
                    },
                    "required": [
                      "model",
                      "messages"
                    ],
                    "additionalProperties": true
                  }
                },
                {
                  "id": "glm-5.3",
                  "label": "GLM-5.3",
                  "doc": "/docs/protocols/glm-5-3",
                  "schema": {
                    "type": "object",
                    "description": "",
                    "properties": {
                      "model": {
                        "type": "string",
                        "description": "A model ID in the current key's group; `GET /v1/models` is authoritative. If the group does not include the model, returns 404 `model_not_found`; image models such as `gpt-image-*` return 400 `image models do not support Chat Completions, please use the Images API` on this endpoint",
                        "enum": [
                          "glm-5.3"
                        ]
                      },
                      "messages": {
                        "type": "array",
                        "description": "Non-empty array, **text only**; images return 400. 1M context",
                        "items": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "role": {
                              "type": "string",
                              "description": "`system` / `user` / `assistant` / `tool`, in OpenAI format"
                            },
                            "content": {
                              "description": "A string, or an array of content parts. Part `{\"type\": \"text\", \"text\": …}`; vision models also accept `{\"type\": \"image_url\", \"image_url\": {\"url\": …}}`. Per-model image requirements are shown under the model picker above",
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "array",
                                  "description": "",
                                  "items": {
                                    "type": "object",
                                    "description": "",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "description": "`text` or `image_url`"
                                      },
                                      "text": {
                                        "type": "string",
                                        "description": "Text when `type` is `text`"
                                      },
                                      "image_url": {
                                        "type": "object",
                                        "description": "Image when `type` is `image_url`",
                                        "properties": {
                                          "url": {
                                            "type": "string",
                                            "description": "HTTP(S) link or `data:` URI; supported forms vary by model"
                                          }
                                        },
                                        "required": [
                                          "url"
                                        ]
                                      }
                                    },
                                    "required": [
                                      "type"
                                    ]
                                  }
                                }
                              ]
                            },
                            "tool_calls": {
                              "type": "array",
                              "description": "`assistant` only: the tool calls returned by the model in the previous turn, sent back unchanged",
                              "items": {
                                "type": "object"
                              }
                            },
                            "tool_call_id": {
                              "type": "string",
                              "description": "`tool` only: must match `tool_calls[].id` from the previous turn"
                            }
                          },
                          "required": [
                            "role"
                          ]
                        },
                        "minItems": 1
                      },
                      "max_tokens": {
                        "type": "integer",
                        "description": "Shared by thinking and answer. Out of range returns 400 `max_tokens` invalid: allowed range [1,131072]",
                        "minimum": 1,
                        "maximum": 131072
                      },
                      "max_completion_tokens": {
                        "type": "integer",
                        "description": "Same as `max_tokens`; the newer OpenAI field name"
                      },
                      "stream": {
                        "type": "boolean",
                        "description": "`true` returns SSE; see [Streaming events](https://hop-base.com/zh-cn/docs/api-reference/streaming-events) for the event format",
                        "default": false
                      },
                      "stream_options": {
                        "type": "object",
                        "description": "Streaming options",
                        "properties": {
                          "include_usage": {
                            "type": "boolean",
                            "description": "When streaming, pass `true` to receive a final event carrying only `usage` (with empty `choices`); if omitted it is not sent. Billing is unaffected",
                            "default": false
                          }
                        }
                      },
                      "tools": {
                        "type": "array",
                        "description": "Function tools in OpenAI function tools format, forwarded as-is.",
                        "items": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "type": {
                              "const": "function",
                              "description": "Always `function`"
                            },
                            "function": {
                              "type": "object",
                              "description": "",
                              "properties": {
                                "name": {
                                  "type": "string",
                                  "description": "Function name"
                                },
                                "description": {
                                  "type": "string",
                                  "description": "What the function does; the model uses it to decide whether to call it"
                                },
                                "parameters": {
                                  "type": "object",
                                  "description": "JSON Schema for the parameters"
                                }
                              },
                              "required": [
                                "name"
                              ]
                            }
                          },
                          "required": [
                            "type",
                            "function"
                          ]
                        }
                      },
                      "tool_choice": {
                        "description": "Same as OpenAI. Returned `tool` results must match a call ID from the previous turn, otherwise 400 `No tool call found for function call output`",
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "object"
                          }
                        ],
                        "default": "auto"
                      },
                      "temperature": {
                        "type": "number",
                        "description": "Sampling temperature, forwarded as-is; range per the model's official spec"
                      },
                      "top_p": {
                        "type": "number",
                        "description": "Nucleus sampling, forwarded as-is; range per the model's official spec"
                      },
                      "reasoning_effort": {
                        "type": "string",
                        "description": "Always thinks: values that disable thinking, such as `none`, return 400",
                        "enum": [
                          "low",
                          "high",
                          "max"
                        ]
                      },
                      "service_tier": {
                        "type": "string",
                        "description": "Only `priority` / `flex` are kept; other values are removed before forwarding, without an error",
                        "enum": [
                          "priority",
                          "flex"
                        ]
                      }
                    },
                    "required": [
                      "model",
                      "messages"
                    ],
                    "additionalProperties": true
                  }
                },
                {
                  "id": "glm-5.3-flash",
                  "label": "GLM-5.3 Flash",
                  "doc": "/docs/protocols/glm-5-3-flash",
                  "schema": {
                    "type": "object",
                    "description": "",
                    "properties": {
                      "model": {
                        "type": "string",
                        "description": "A model ID in the current key's group; `GET /v1/models` is authoritative. If the group does not include the model, returns 404 `model_not_found`; image models such as `gpt-image-*` return 400 `image models do not support Chat Completions, please use the Images API` on this endpoint",
                        "enum": [
                          "glm-5.3-flash"
                        ]
                      },
                      "messages": {
                        "type": "array",
                        "description": "Non-empty array; may contain text, images, video and files. 1M context",
                        "items": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "role": {
                              "type": "string",
                              "description": "`system` / `user` / `assistant` / `tool`, in OpenAI format"
                            },
                            "content": {
                              "description": "A string, or an array of content parts. Part `{\"type\": \"text\", \"text\": …}`; vision models also accept `{\"type\": \"image_url\", \"image_url\": {\"url\": …}}`. Per-model image requirements are shown under the model picker above",
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "array",
                                  "description": "",
                                  "items": {
                                    "type": "object",
                                    "description": "",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "description": "`text` or `image_url`"
                                      },
                                      "text": {
                                        "type": "string",
                                        "description": "Text when `type` is `text`"
                                      },
                                      "image_url": {
                                        "type": "object",
                                        "description": "Image when `type` is `image_url`",
                                        "properties": {
                                          "url": {
                                            "type": "string",
                                            "description": "HTTP(S) link or `data:` URI; supported forms vary by model"
                                          }
                                        },
                                        "required": [
                                          "url"
                                        ]
                                      }
                                    },
                                    "required": [
                                      "type"
                                    ]
                                  }
                                }
                              ]
                            },
                            "tool_calls": {
                              "type": "array",
                              "description": "`assistant` only: the tool calls returned by the model in the previous turn, sent back unchanged",
                              "items": {
                                "type": "object"
                              }
                            },
                            "tool_call_id": {
                              "type": "string",
                              "description": "`tool` only: must match `tool_calls[].id` from the previous turn"
                            }
                          },
                          "required": [
                            "role"
                          ]
                        },
                        "minItems": 1
                      },
                      "max_tokens": {
                        "type": "integer",
                        "description": "Up to 128K (official cap), shared by thinking and answer"
                      },
                      "max_completion_tokens": {
                        "type": "integer",
                        "description": "Same as `max_tokens`; the newer OpenAI field name"
                      },
                      "stream": {
                        "type": "boolean",
                        "description": "`true` returns SSE; see [Streaming events](https://hop-base.com/zh-cn/docs/api-reference/streaming-events) for the event format",
                        "default": false
                      },
                      "stream_options": {
                        "type": "object",
                        "description": "Streaming options",
                        "properties": {
                          "include_usage": {
                            "type": "boolean",
                            "description": "When streaming, pass `true` to receive a final event carrying only `usage` (with empty `choices`); if omitted it is not sent. Billing is unaffected",
                            "default": false
                          }
                        }
                      },
                      "tools": {
                        "type": "array",
                        "description": "Function tools in OpenAI function tools format, forwarded as-is.",
                        "items": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "type": {
                              "const": "function",
                              "description": "Always `function`"
                            },
                            "function": {
                              "type": "object",
                              "description": "",
                              "properties": {
                                "name": {
                                  "type": "string",
                                  "description": "Function name"
                                },
                                "description": {
                                  "type": "string",
                                  "description": "What the function does; the model uses it to decide whether to call it"
                                },
                                "parameters": {
                                  "type": "object",
                                  "description": "JSON Schema for the parameters"
                                }
                              },
                              "required": [
                                "name"
                              ]
                            }
                          },
                          "required": [
                            "type",
                            "function"
                          ]
                        }
                      },
                      "tool_choice": {
                        "description": "`auto` / `none` / `required` or a specific function, forwarded as-is",
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "object"
                          }
                        ]
                      },
                      "temperature": {
                        "type": "number",
                        "description": "No gateway range; `1` recommended"
                      },
                      "top_p": {
                        "type": "number",
                        "description": "No gateway range; `0.95` recommended"
                      },
                      "reasoning_effort": {
                        "type": "string",
                        "description": "`max` recommended; thinking can only be on, not off",
                        "enum": [
                          "low",
                          "high",
                          "max"
                        ]
                      },
                      "service_tier": {
                        "type": "string",
                        "description": "Only `priority` / `flex` are kept; other values are removed before forwarding, without an error",
                        "enum": [
                          "priority",
                          "flex"
                        ]
                      },
                      "tool_stream": {
                        "type": "boolean",
                        "description": "Recommended `true` when streaming with `tools`, so tool arguments stream incrementally",
                        "default": false
                      }
                    },
                    "required": [
                      "model",
                      "messages"
                    ],
                    "additionalProperties": true
                  }
                },
                {
                  "id": "qwen",
                  "label": "Qwen",
                  "doc": "/docs/protocols/qwen",
                  "schema": {
                    "type": "object",
                    "description": "",
                    "properties": {
                      "model": {
                        "type": "string",
                        "description": "A model ID in the current key's group; `GET /v1/models` is authoritative. If the group does not include the model, returns 404 `model_not_found`; image models such as `gpt-image-*` return 400 `image models do not support Chat Completions, please use the Images API` on this endpoint",
                        "enum": [
                          "qwen3.7-flash",
                          "qwen3.7-max",
                          "qwen3.7-plus",
                          "qwen3.8-flash",
                          "qwen3.8-max"
                        ]
                      },
                      "messages": {
                        "type": "array",
                        "description": "Non-empty array; `qwen3.7-max` is text only, other models accept images and video; image width and height must exceed 10 px. `qwen3.8-max` measured input cap is 991,808 tokens; beyond that returns 400 `Range of input length should be [1, 991808]`",
                        "items": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "role": {
                              "type": "string",
                              "description": "`system` / `user` / `assistant` / `tool`, in OpenAI format"
                            },
                            "content": {
                              "description": "A string, or an array of content parts. Part `{\"type\": \"text\", \"text\": …}`; vision models also accept `{\"type\": \"image_url\", \"image_url\": {\"url\": …}}`. Per-model image requirements are shown under the model picker above",
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "array",
                                  "description": "",
                                  "items": {
                                    "type": "object",
                                    "description": "",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "description": "`text` or `image_url`"
                                      },
                                      "text": {
                                        "type": "string",
                                        "description": "Text when `type` is `text`"
                                      },
                                      "image_url": {
                                        "type": "object",
                                        "description": "Image when `type` is `image_url`",
                                        "properties": {
                                          "url": {
                                            "type": "string",
                                            "description": "HTTP(S) link or `data:` URI; supported forms vary by model"
                                          }
                                        },
                                        "required": [
                                          "url"
                                        ]
                                      }
                                    },
                                    "required": [
                                      "type"
                                    ]
                                  }
                                }
                              ]
                            },
                            "tool_calls": {
                              "type": "array",
                              "description": "`assistant` only: the tool calls returned by the model in the previous turn, sent back unchanged",
                              "items": {
                                "type": "object"
                              }
                            },
                            "tool_call_id": {
                              "type": "string",
                              "description": "`tool` only: must match `tool_calls[].id` from the previous turn"
                            }
                          },
                          "required": [
                            "role"
                          ]
                        },
                        "minItems": 1
                      },
                      "max_tokens": {
                        "type": "integer",
                        "description": "Up to 131,072 (official cap)",
                        "maximum": 131072
                      },
                      "max_completion_tokens": {
                        "type": "integer",
                        "description": "Same as `max_tokens`; the newer OpenAI field name"
                      },
                      "stream": {
                        "type": "boolean",
                        "description": "`true` returns SSE; see [Streaming events](https://hop-base.com/zh-cn/docs/api-reference/streaming-events) for the event format",
                        "default": false
                      },
                      "stream_options": {
                        "type": "object",
                        "description": "Streaming options",
                        "properties": {
                          "include_usage": {
                            "type": "boolean",
                            "description": "When streaming, pass `true` to receive a final event carrying only `usage` (with empty `choices`); if omitted it is not sent. Billing is unaffected",
                            "default": false
                          }
                        }
                      },
                      "tools": {
                        "type": "array",
                        "description": "Function tools in OpenAI function tools format, forwarded as-is.",
                        "items": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "type": {
                              "const": "function",
                              "description": "Always `function`"
                            },
                            "function": {
                              "type": "object",
                              "description": "",
                              "properties": {
                                "name": {
                                  "type": "string",
                                  "description": "Function name"
                                },
                                "description": {
                                  "type": "string",
                                  "description": "What the function does; the model uses it to decide whether to call it"
                                },
                                "parameters": {
                                  "type": "object",
                                  "description": "JSON Schema for the parameters"
                                }
                              },
                              "required": [
                                "name"
                              ]
                            }
                          },
                          "required": [
                            "type",
                            "function"
                          ]
                        }
                      },
                      "tool_choice": {
                        "description": "Same as OpenAI. In thinking mode it cannot be `required` or a specific function; doing so returns 400",
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "object"
                          }
                        ],
                        "default": "auto"
                      },
                      "temperature": {
                        "type": "number",
                        "description": "Sampling temperature, forwarded as-is; range per the model's official spec"
                      },
                      "top_p": {
                        "type": "number",
                        "description": "Nucleus sampling, forwarded as-is; range per the model's official spec"
                      },
                      "reasoning_effort": {
                        "type": "string",
                        "description": "Values verified to work",
                        "enum": [
                          "low",
                          "high",
                          "max"
                        ]
                      },
                      "service_tier": {
                        "type": "string",
                        "description": "Only `priority` / `flex` are kept; other values are removed before forwarding, without an error",
                        "enum": [
                          "priority",
                          "flex"
                        ]
                      },
                      "enable_thinking": {
                        "type": "boolean",
                        "description": "Qwen-specific, passed through"
                      },
                      "thinking_budget": {
                        "type": "integer",
                        "description": "Cannot be set together with `reasoning_effort`; doing so returns 400"
                      },
                      "enable_search": {
                        "type": "boolean",
                        "description": "Qwen-specific, passed through"
                      },
                      "response_format": {
                        "type": "object",
                        "description": "JSON mode, same behavior as the official API"
                      }
                    },
                    "required": [
                      "model",
                      "messages"
                    ],
                    "additionalProperties": true
                  }
                },
                {
                  "id": "deepseek",
                  "label": "DeepSeek",
                  "doc": "/docs/protocols/deepseek",
                  "schema": {
                    "type": "object",
                    "description": "",
                    "properties": {
                      "model": {
                        "type": "string",
                        "description": "A model ID in the current key's group; `GET /v1/models` is authoritative. If the group does not include the model, returns 404 `model_not_found`; image models such as `gpt-image-*` return 400 `image models do not support Chat Completions, please use the Images API` on this endpoint",
                        "enum": [
                          "deepseek-v4-flash-202605",
                          "deepseek-v4-pro-202606",
                          "deepseek-v4.1-flash"
                        ]
                      },
                      "messages": {
                        "type": "array",
                        "description": "Non-empty array; `role` is `system` / `user` / `assistant` / `tool` / `developer`. Image input on `deepseek-v4.1-flash` only: `image_url.url` may be a `data:` URI or an `https://` link",
                        "items": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "role": {
                              "type": "string",
                              "description": "`system` / `user` / `assistant` / `tool`, in OpenAI format"
                            },
                            "content": {
                              "description": "A string, or an array of content parts. Part `{\"type\": \"text\", \"text\": …}`; vision models also accept `{\"type\": \"image_url\", \"image_url\": {\"url\": …}}`. Per-model image requirements are shown under the model picker above",
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "array",
                                  "description": "",
                                  "items": {
                                    "type": "object",
                                    "description": "",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "description": "`text` or `image_url`"
                                      },
                                      "text": {
                                        "type": "string",
                                        "description": "Text when `type` is `text`"
                                      },
                                      "image_url": {
                                        "type": "object",
                                        "description": "Image when `type` is `image_url`",
                                        "properties": {
                                          "url": {
                                            "type": "string",
                                            "description": "HTTP(S) link or `data:` URI; supported forms vary by model"
                                          }
                                        },
                                        "required": [
                                          "url"
                                        ]
                                      }
                                    },
                                    "required": [
                                      "type"
                                    ]
                                  }
                                }
                              ]
                            },
                            "tool_calls": {
                              "type": "array",
                              "description": "`assistant` only: the tool calls returned by the model in the previous turn, sent back unchanged",
                              "items": {
                                "type": "object"
                              }
                            },
                            "tool_call_id": {
                              "type": "string",
                              "description": "`tool` only: must match `tool_calls[].id` from the previous turn"
                            }
                          },
                          "required": [
                            "role"
                          ]
                        },
                        "minItems": 1
                      },
                      "max_tokens": {
                        "type": "integer",
                        "description": "Non-negative integer; output caps: V4.1 Flash and V4 Flash 384,000, V4 Pro 393,216. Shared by thinking and answer; negative values return 400; values above the cap do not error, the output is silently truncated",
                        "minimum": 0
                      },
                      "max_completion_tokens": {
                        "type": "integer",
                        "description": "Same as `max_tokens`; the newer OpenAI field name"
                      },
                      "stream": {
                        "type": "boolean",
                        "description": "`true` returns SSE; see [Streaming events](https://hop-base.com/zh-cn/docs/api-reference/streaming-events) for the event format",
                        "default": false
                      },
                      "stream_options": {
                        "type": "object",
                        "description": "Streaming options",
                        "properties": {
                          "include_usage": {
                            "type": "boolean",
                            "description": "When streaming, pass `true` to receive a final event carrying only `usage` (with empty `choices`); if omitted it is not sent. Billing is unaffected",
                            "default": false
                          }
                        }
                      },
                      "tools": {
                        "type": "array",
                        "description": "Function tools in OpenAI function tools format, forwarded as-is.",
                        "items": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "type": {
                              "const": "function",
                              "description": "Always `function`"
                            },
                            "function": {
                              "type": "object",
                              "description": "",
                              "properties": {
                                "name": {
                                  "type": "string",
                                  "description": "Function name"
                                },
                                "description": {
                                  "type": "string",
                                  "description": "What the function does; the model uses it to decide whether to call it"
                                },
                                "parameters": {
                                  "type": "object",
                                  "description": "JSON Schema for the parameters"
                                }
                              },
                              "required": [
                                "name"
                              ]
                            }
                          },
                          "required": [
                            "type",
                            "function"
                          ]
                        }
                      },
                      "tool_choice": {
                        "description": "`auto` / `none` / `required` / a specific function",
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "object"
                          }
                        ],
                        "default": "auto"
                      },
                      "temperature": {
                        "type": "number",
                        "description": "Values above 2 return 400 `expected a value <= 2`",
                        "minimum": 0,
                        "maximum": 2
                      },
                      "top_p": {
                        "type": "number",
                        "description": "Nucleus sampling, forwarded as-is; range per the model's official spec"
                      },
                      "reasoning_effort": {
                        "type": "string",
                        "description": "Values verified to work",
                        "enum": [
                          "low",
                          "medium",
                          "high"
                        ]
                      },
                      "service_tier": {
                        "type": "string",
                        "description": "Only `priority` / `flex` are kept; other values are removed before forwarding, without an error",
                        "enum": [
                          "priority",
                          "flex"
                        ]
                      },
                      "thinking": {
                        "type": "object",
                        "description": "`{\"type\": …}`; other values (such as `auto`) return 400. On by default for V4.1 Flash",
                        "properties": {
                          "type": {
                            "enum": [
                              "enabled",
                              "disabled",
                              "adaptive"
                            ]
                          }
                        }
                      },
                      "prefix": {
                        "type": "boolean",
                        "description": "Prefix continuation: only allowed on the last `assistant` message",
                        "default": false
                      }
                    },
                    "required": [
                      "model",
                      "messages"
                    ],
                    "additionalProperties": true
                  }
                },
                {
                  "id": "grok",
                  "label": "Grok",
                  "doc": "/docs/protocols/grok",
                  "schema": {
                    "type": "object",
                    "description": "",
                    "properties": {
                      "model": {
                        "type": "string",
                        "description": "A model ID in the current key's group; `GET /v1/models` is authoritative. If the group does not include the model, returns 404 `model_not_found`; image models such as `gpt-image-*` return 400 `image models do not support Chat Completions, please use the Images API` on this endpoint",
                        "enum": [
                          "grok-4.20-0309-reasoning",
                          "grok-4.20-multi-agent-0309",
                          "grok-4.3",
                          "grok-4.5",
                          "grok-4.6"
                        ]
                      },
                      "messages": {
                        "type": "array",
                        "description": "Conversation messages. Missing returns 400 `missing messages field`; an empty array returns 400 `messages must not be an empty array`",
                        "items": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "role": {
                              "type": "string",
                              "description": "`system` / `user` / `assistant` / `tool`, in OpenAI format"
                            },
                            "content": {
                              "description": "A string, or an array of content parts. Part `{\"type\": \"text\", \"text\": …}`; vision models also accept `{\"type\": \"image_url\", \"image_url\": {\"url\": …}}`. Per-model image requirements are shown under the model picker above",
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "array",
                                  "description": "",
                                  "items": {
                                    "type": "object",
                                    "description": "",
                                    "properties": {
                                      "type": {
                                        "type": "string",
                                        "description": "`text` or `image_url`"
                                      },
                                      "text": {
                                        "type": "string",
                                        "description": "Text when `type` is `text`"
                                      },
                                      "image_url": {
                                        "type": "object",
                                        "description": "Image when `type` is `image_url`",
                                        "properties": {
                                          "url": {
                                            "type": "string",
                                            "description": "HTTP(S) link or `data:` URI; supported forms vary by model"
                                          }
                                        },
                                        "required": [
                                          "url"
                                        ]
                                      }
                                    },
                                    "required": [
                                      "type"
                                    ]
                                  }
                                }
                              ]
                            },
                            "tool_calls": {
                              "type": "array",
                              "description": "`assistant` only: the tool calls returned by the model in the previous turn, sent back unchanged",
                              "items": {
                                "type": "object"
                              }
                            },
                            "tool_call_id": {
                              "type": "string",
                              "description": "`tool` only: must match `tool_calls[].id` from the previous turn"
                            }
                          },
                          "required": [
                            "role"
                          ]
                        },
                        "minItems": 1
                      },
                      "max_tokens": {
                        "type": "integer",
                        "description": "No gateway cap; bounded by the context window. Officially includes reasoning tokens"
                      },
                      "max_completion_tokens": {
                        "type": "integer",
                        "description": "Same as `max_tokens`; the newer OpenAI field name"
                      },
                      "stream": {
                        "type": "boolean",
                        "description": "`true` returns SSE; see [Streaming events](https://hop-base.com/zh-cn/docs/api-reference/streaming-events) for the event format",
                        "default": false
                      },
                      "stream_options": {
                        "type": "object",
                        "description": "Streaming options",
                        "properties": {
                          "include_usage": {
                            "type": "boolean",
                            "description": "When streaming, pass `true` to receive a final event carrying only `usage` (with empty `choices`); if omitted it is not sent. Billing is unaffected",
                            "default": false
                          }
                        }
                      },
                      "tools": {
                        "type": "array",
                        "description": "Function tools and server-side tools; server-side tools are billed per call",
                        "items": {
                          "type": "object"
                        }
                      },
                      "tool_choice": {
                        "description": "`auto` / `none` / `required` or a specific function, forwarded as-is",
                        "anyOf": [
                          {
                            "type": "string"
                          },
                          {
                            "type": "object"
                          }
                        ]
                      },
                      "temperature": {
                        "type": "number",
                        "description": "0–2 (official)",
                        "minimum": 0,
                        "maximum": 2
                      },
                      "top_p": {
                        "type": "number",
                        "description": "0–1 (official); officially recommended to use either this or `temperature`, not both",
                        "minimum": 0,
                        "maximum": 1
                      },
                      "reasoning_effort": {
                        "type": "string",
                        "description": "`grok-4.6`: `low` / `medium` / `high` / `xhigh`; `grok-4.5`: `low` / `medium` / `high` (official). Only these two models expose it officially; reasoning cannot be disabled",
                        "enum": [
                          "low",
                          "medium",
                          "high",
                          "xhigh"
                        ],
                        "default": "high"
                      },
                      "service_tier": {
                        "type": "string",
                        "description": "Only `priority` / `flex` are kept; other values are removed before forwarding, without an error",
                        "enum": [
                          "priority",
                          "flex"
                        ]
                      },
                      "presence_penalty": {
                        "not": {},
                        "description": "**Not supported** (official): reasoning models reject it and return an error"
                      },
                      "frequency_penalty": {
                        "not": {},
                        "description": "**Not supported** (official)"
                      },
                      "stop": {
                        "not": {},
                        "description": "**Not supported** (official)"
                      }
                    },
                    "required": [
                      "model",
                      "messages"
                    ],
                    "additionalProperties": true
                  }
                }
              ]
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success. Non-streaming returns `chat.completion` JSON; with `stream: true` it returns SSE (`text/event-stream`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Non-streaming response: a `chat.completion` object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "ID of this completion"
                    },
                    "object": {
                      "const": "chat.completion",
                      "description": "Always `chat.completion`"
                    },
                    "created": {
                      "type": "integer",
                      "description": "Unix seconds"
                    },
                    "model": {
                      "type": "string",
                      "description": "Model ID actually used"
                    },
                    "choices": {
                      "type": "array",
                      "description": "Candidate replies; most models return only 1",
                      "items": {
                        "type": "object",
                        "description": "",
                        "properties": {
                          "index": {
                            "type": "integer",
                            "description": "Index"
                          },
                          "message": {
                            "type": "object",
                            "description": "Model reply",
                            "properties": {
                              "role": {
                                "const": "assistant",
                                "description": "Always `assistant`"
                              },
                              "content": {
                                "type": [
                                  "string",
                                  "null"
                                ],
                                "description": "Reply text; `null` when the model only calls tools"
                              },
                              "reasoning_content": {
                                "type": "string",
                                "description": "Reasoning content (returned by DeepSeek and other models)"
                              },
                              "tool_calls": {
                                "type": "array",
                                "description": "Functions the model wants to call; after running them, send the results back in `role: \"tool\"` messages",
                                "items": {
                                  "type": "object",
                                  "description": "",
                                  "properties": {
                                    "id": {
                                      "type": "string",
                                      "description": "Call ID; put it in `tool_call_id` when returning the result"
                                    },
                                    "type": {
                                      "const": "function"
                                    },
                                    "function": {
                                      "type": "object",
                                      "description": "",
                                      "properties": {
                                        "name": {
                                          "type": "string",
                                          "description": "Function name"
                                        },
                                        "arguments": {
                                          "type": "string",
                                          "description": "Arguments as a JSON string"
                                        }
                                      }
                                    }
                                  }
                                }
                              }
                            }
                          },
                          "finish_reason": {
                            "type": "string",
                            "description": "`stop` / `length` / `tool_calls`, etc.; `length` means the output cap was hit"
                          }
                        }
                      }
                    },
                    "usage": {
                      "type": "object",
                      "description": "Token usage",
                      "properties": {
                        "prompt_tokens": {
                          "type": "integer",
                          "description": "Input tokens"
                        },
                        "completion_tokens": {
                          "type": "integer",
                          "description": "Output tokens; whether reasoning tokens are included varies by model, see each model page"
                        },
                        "total_tokens": {
                          "type": "integer",
                          "description": "Total"
                        },
                        "completion_tokens_details": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "reasoning_tokens": {
                              "type": "integer",
                              "description": "Reasoning tokens (listed separately by some models)"
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "text": {
                    "summary": "Text",
                    "value": {
                      "id": "chatcmpl-EXAMPLE",
                      "object": "chat.completion",
                      "created": 1790222400,
                      "model": "gpt-5.6-sol",
                      "choices": [
                        {
                          "index": 0,
                          "message": {
                            "role": "assistant",
                            "content": "Hello! How can I help you?"
                          },
                          "finish_reason": "stop"
                        }
                      ],
                      "usage": {
                        "prompt_tokens": 8,
                        "completion_tokens": 9,
                        "total_tokens": 17
                      }
                    }
                  },
                  "tools": {
                    "summary": "Tool calls",
                    "value": {
                      "id": "chatcmpl-EXAMPLE",
                      "object": "chat.completion",
                      "created": 1790222400,
                      "model": "gpt-5.6-sol",
                      "choices": [
                        {
                          "index": 0,
                          "message": {
                            "role": "assistant",
                            "content": null,
                            "tool_calls": [
                              {
                                "id": "call_EXAMPLE",
                                "type": "function",
                                "function": {
                                  "name": "get_weather",
                                  "arguments": "{\"city\":\"Shanghai\"}"
                                }
                              }
                            ]
                          },
                          "finish_reason": "tool_calls"
                        }
                      ],
                      "usage": {
                        "prompt_tokens": 61,
                        "completion_tokens": 17,
                        "total_tokens": 78
                      }
                    }
                  },
                  "image": {
                    "summary": "Image input",
                    "value": {
                      "id": "chatcmpl-EXAMPLE",
                      "object": "chat.completion",
                      "created": 1790222400,
                      "model": "deepseek-v4.1-flash",
                      "choices": [
                        {
                          "index": 0,
                          "message": {
                            "role": "assistant",
                            "reasoning_content": "The chart is a monthly bar chart...",
                            "content": "The chart shows Q3 sales growing quarter over quarter, peaking in September."
                          },
                          "finish_reason": "stop"
                        }
                      ],
                      "usage": {
                        "prompt_tokens": 812,
                        "completion_tokens": 96,
                        "total_tokens": 908
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Unreadable request body, missing `messages`, etc.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or expired API key (`missing_api_key` / `invalid_api_key` / `api_key_expired`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Balance, or key / member / department quota, exhausted (`insufficient_quota`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "The model is not in this key's group (`model_not_found`), or the path does not belong to the group (`route_not_found`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "Request body over 60 MB (`request_too_large`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Account or key concurrency cap reached (`user_concurrency_limit` / `apikey_concurrency_limit`), with `Retry-After`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-hopbase-slug": "chat-completions",
        "x-hopbase-summary": "OpenAI-compatible Chat Completions: shared by GPT, Gemini, GLM, Qwen, DeepSeek, Grok and other chat models.",
        "x-hopbase-docs": "https://hop-base.com/zh-cn/docs/api-reference/chat-completions",
        "x-hopbase-scenarios": [
          {
            "id": "text",
            "label": "Text",
            "request": {
              "body": {
                "model": "gpt-5.6-sol",
                "messages": [
                  {
                    "role": "user",
                    "content": "Hello"
                  }
                ]
              }
            },
            "response": {
              "status": 200,
              "body": {
                "id": "chatcmpl-EXAMPLE",
                "object": "chat.completion",
                "created": 1790222400,
                "model": "gpt-5.6-sol",
                "choices": [
                  {
                    "index": 0,
                    "message": {
                      "role": "assistant",
                      "content": "Hello! How can I help you?"
                    },
                    "finish_reason": "stop"
                  }
                ],
                "usage": {
                  "prompt_tokens": 8,
                  "completion_tokens": 9,
                  "total_tokens": 17
                }
              }
            }
          },
          {
            "id": "stream",
            "label": "Streaming",
            "request": {
              "stream": true,
              "body": {
                "model": "gpt-5.6-sol",
                "stream": true,
                "stream_options": {
                  "include_usage": true
                },
                "messages": [
                  {
                    "role": "user",
                    "content": "Introduce yourself in three sentences"
                  }
                ]
              }
            },
            "response": {
              "status": 200,
              "contentType": "text/event-stream",
              "text": "data: {\"id\":\"chatcmpl-EXAMPLE\",\"object\":\"chat.completion.chunk\",\"model\":\"gpt-5.6-sol\",\"choices\":[{\"index\":0,\"delta\":{\"role\":\"assistant\",\"content\":\"I am\"},\"finish_reason\":null}]}\n\ndata: {\"id\":\"chatcmpl-EXAMPLE\",\"object\":\"chat.completion.chunk\",\"model\":\"gpt-5.6-sol\",\"choices\":[{\"index\":0,\"delta\":{\"content\":\" an AI assistant.\"},\"finish_reason\":null}]}\n\n: hopbase-keepalive\n\ndata: {\"id\":\"chatcmpl-EXAMPLE\",\"object\":\"chat.completion.chunk\",\"model\":\"gpt-5.6-sol\",\"choices\":[{\"index\":0,\"delta\":{},\"finish_reason\":\"stop\"}]}\n\ndata: {\"id\":\"chatcmpl-EXAMPLE\",\"object\":\"chat.completion.chunk\",\"model\":\"gpt-5.6-sol\",\"choices\":[],\"usage\":{\"prompt_tokens\":14,\"completion_tokens\":52,\"total_tokens\":66}}\n\ndata: [DONE]"
            }
          },
          {
            "id": "tools",
            "label": "Tool calls",
            "request": {
              "body": {
                "model": "gpt-5.6-sol",
                "messages": [
                  {
                    "role": "user",
                    "content": "What's the weather in Shanghai today?"
                  }
                ],
                "tools": [
                  {
                    "type": "function",
                    "function": {
                      "name": "get_weather",
                      "description": "Get the weather for a city",
                      "parameters": {
                        "type": "object",
                        "properties": {
                          "city": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "city"
                        ]
                      }
                    }
                  }
                ]
              }
            },
            "response": {
              "status": 200,
              "body": {
                "id": "chatcmpl-EXAMPLE",
                "object": "chat.completion",
                "created": 1790222400,
                "model": "gpt-5.6-sol",
                "choices": [
                  {
                    "index": 0,
                    "message": {
                      "role": "assistant",
                      "content": null,
                      "tool_calls": [
                        {
                          "id": "call_EXAMPLE",
                          "type": "function",
                          "function": {
                            "name": "get_weather",
                            "arguments": "{\"city\":\"Shanghai\"}"
                          }
                        }
                      ]
                    },
                    "finish_reason": "tool_calls"
                  }
                ],
                "usage": {
                  "prompt_tokens": 61,
                  "completion_tokens": 17,
                  "total_tokens": 78
                }
              }
            }
          },
          {
            "id": "image",
            "label": "Image input",
            "request": {
              "body": {
                "model": "deepseek-v4.1-flash",
                "messages": [
                  {
                    "role": "user",
                    "content": [
                      {
                        "type": "text",
                        "text": "What is the main takeaway of this chart?"
                      },
                      {
                        "type": "image_url",
                        "image_url": {
                          "url": "https://example.com/chart.png"
                        }
                      }
                    ]
                  }
                ]
              }
            },
            "response": {
              "status": 200,
              "body": {
                "id": "chatcmpl-EXAMPLE",
                "object": "chat.completion",
                "created": 1790222400,
                "model": "deepseek-v4.1-flash",
                "choices": [
                  {
                    "index": 0,
                    "message": {
                      "role": "assistant",
                      "reasoning_content": "The chart is a monthly bar chart...",
                      "content": "The chart shows Q3 sales growing quarter over quarter, peaking in September."
                    },
                    "finish_reason": "stop"
                  }
                ],
                "usage": {
                  "prompt_tokens": 812,
                  "completion_tokens": 96,
                  "total_tokens": 908
                }
              }
            }
          }
        ],
        "x-hopbase-related": [
          {
            "label": "OpenAI SDK integration",
            "href": "/docs/protocols/openai-sdk"
          },
          {
            "label": "Streaming events",
            "href": "/docs/api-reference/streaming-events"
          },
          {
            "label": "Error codes and retries",
            "href": "/docs/reference/errors"
          }
        ],
        "x-hopbase-sources": [
          "content/docs/protocols/openai-sdk.zh-cn.mdx#支持的请求参数",
          "content/docs/protocols/{gemini,glm-5-3,glm-5-3-flash,qwen,deepseek,grok}.zh-cn.mdx#请求参数",
          "content/docs/reference/errors.zh-cn.mdx"
        ]
      }
    },
    "/v1/responses": {
      "post": {
        "operationId": "createResponse",
        "summary": "Create response",
        "description": "OpenAI Responses-compatible endpoint; Codex CLI uses it. HopBase Responses is **stateless**: `store` is always `false` and `previous_response_id` is removed, so send the full `input` every turn in multi-turn conversations.\n\nFields not listed are forwarded as-is; for fields a model does not accept (such as DeepSeek's `truncation` and `reasoning.summary`), each model page says whether they are silently dropped. If a stream fails midway, it is reported as `event: response.failed` and the HTTP status stays 200.",
        "tags": [
          "Chat"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "",
                "properties": {
                  "model": {
                    "type": "string",
                    "description": "A model ID in the current key's group. Groups that support Responses: GPT (Codex), GLM-5.3, Qwen, Grok, and `deepseek-v4.1-flash`; Gemini does not"
                  },
                  "input": {
                    "description": "A string is wrapped into a single user message automatically; a message array also works. Qwen content parts accept only `input_text`, `input_image` and `input_file`, not video",
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array",
                        "description": "",
                        "items": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "role": {
                              "type": "string",
                              "description": "`user` / `assistant` / `system` / `developer`"
                            },
                            "content": {
                              "description": "A string or an array of content parts",
                              "anyOf": [
                                {
                                  "type": "string"
                                },
                                {
                                  "type": "array"
                                }
                              ]
                            }
                          }
                        }
                      }
                    ]
                  },
                  "max_output_tokens": {
                    "type": "integer",
                    "description": "Output cap. The gateway does not truncate or rewrite it; the limit follows the model's official spec"
                  },
                  "stream": {
                    "type": "boolean",
                    "description": "`true` returns a Responses SSE event stream; see [Streaming events](https://hop-base.com/zh-cn/docs/api-reference/streaming-events)",
                    "default": false
                  },
                  "tools": {
                    "type": "array",
                    "description": "Tool definitions, forwarded as-is. Responses function tools are flat (`name` sits next to `type`), unlike Chat Completions",
                    "items": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "type": {
                          "type": "string",
                          "description": "`function`, or a server-side tool type the model supports"
                        },
                        "name": {
                          "type": "string",
                          "description": "Function name"
                        },
                        "description": {
                          "type": "string",
                          "description": "What the function does"
                        },
                        "parameters": {
                          "type": "object",
                          "description": "JSON Schema for the parameters"
                        }
                      },
                      "required": [
                        "type"
                      ]
                    }
                  },
                  "tool_choice": {
                    "description": "Forwarded as-is",
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "object"
                      }
                    ]
                  },
                  "reasoning": {
                    "type": "object",
                    "description": "Reasoning config, forwarded as-is. Codex CLI's `model_reasoning_effort` is written here",
                    "properties": {
                      "effort": {
                        "type": "string",
                        "description": "GPT: `low` / `medium` / `high` / `xhigh`; higher effort thinks longer and uses more tokens. `grok-4.20-multi-agent-0309` uses it to set the number of collaborating agents"
                      }
                    }
                  },
                  "service_tier": {
                    "type": "string",
                    "description": "Only `priority` / `flex` are kept; other values are removed before forwarding",
                    "enum": [
                      "priority",
                      "flex"
                    ]
                  },
                  "previous_response_id": {
                    "type": "string",
                    "description": "**Not supported**: the gateway removes this field and does not continue the previous turn. For multi-turn conversations, include the full history in `input`"
                  },
                  "store": {
                    "const": false,
                    "default": false,
                    "description": "Always `false`: responses are not stored server-side and cannot be retrieved by ID later"
                  }
                },
                "required": [
                  "model",
                  "input"
                ],
                "additionalProperties": true
              },
              "examples": {
                "text": {
                  "summary": "Text",
                  "value": {
                    "model": "gpt-5.6-sol",
                    "input": "Hello"
                  }
                },
                "stream": {
                  "summary": "Streaming",
                  "value": {
                    "model": "gpt-5.6-sol",
                    "input": "Introduce yourself in three sentences",
                    "stream": true
                  }
                },
                "reasoning": {
                  "summary": "Reasoning",
                  "value": {
                    "model": "gpt-6-astra",
                    "input": "Prove that the square root of 2 is irrational",
                    "reasoning": {
                      "effort": "high"
                    }
                  }
                },
                "tools": {
                  "summary": "Tool calls",
                  "value": {
                    "model": "gpt-5.6-sol",
                    "input": "What's the weather in Shanghai today?",
                    "tools": [
                      {
                        "type": "function",
                        "name": "get_weather",
                        "description": "Get the weather for a city",
                        "parameters": {
                          "type": "object",
                          "properties": {
                            "city": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "city"
                          ]
                        }
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success. Non-streaming returns `response` JSON; with `stream: true` it returns SSE",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "`response` object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "Response ID (`store` is always `false`, so it cannot be retrieved by ID)"
                    },
                    "object": {
                      "const": "response"
                    },
                    "created_at": {
                      "type": "integer",
                      "description": "Unix seconds"
                    },
                    "status": {
                      "type": "string",
                      "description": "`completed` / `incomplete` / `failed`"
                    },
                    "model": {
                      "type": "string",
                      "description": "Model ID"
                    },
                    "output": {
                      "type": "array",
                      "description": "Output items: `message`, `reasoning`, `function_call`, etc.",
                      "items": {
                        "type": "object",
                        "description": "",
                        "properties": {
                          "type": {
                            "type": "string",
                            "description": "`message` / `reasoning` / `function_call`"
                          },
                          "role": {
                            "type": "string",
                            "description": "`assistant` for `message`"
                          },
                          "content": {
                            "type": "array",
                            "description": "Content parts of a `message`",
                            "items": {
                              "type": "object",
                              "description": "",
                              "properties": {
                                "type": {
                                  "type": "string",
                                  "description": "`output_text`"
                                },
                                "text": {
                                  "type": "string",
                                  "description": "Output text"
                                }
                              }
                            }
                          },
                          "name": {
                            "type": "string",
                            "description": "`function_call`: function name"
                          },
                          "arguments": {
                            "type": "string",
                            "description": "`function_call`: arguments as a JSON string"
                          },
                          "call_id": {
                            "type": "string",
                            "description": "`function_call`: referenced when returning the result"
                          }
                        }
                      }
                    },
                    "usage": {
                      "type": "object",
                      "description": "Token usage",
                      "properties": {
                        "input_tokens": {
                          "type": "integer",
                          "description": "Input tokens"
                        },
                        "output_tokens": {
                          "type": "integer",
                          "description": "Output tokens, including reasoning tokens"
                        },
                        "total_tokens": {
                          "type": "integer",
                          "description": "Total"
                        },
                        "output_tokens_details": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "reasoning_tokens": {
                              "type": "integer",
                              "description": "Of which reasoning tokens"
                            }
                          }
                        }
                      }
                    },
                    "error": {
                      "type": [
                        "object",
                        "null"
                      ],
                      "description": "Error on failure"
                    }
                  }
                },
                "examples": {
                  "text": {
                    "summary": "Text",
                    "value": {
                      "id": "resp_EXAMPLE",
                      "object": "response",
                      "created_at": 1790222400,
                      "status": "completed",
                      "model": "gpt-5.6-sol",
                      "output": [
                        {
                          "type": "message",
                          "id": "msg_EXAMPLE",
                          "role": "assistant",
                          "status": "completed",
                          "content": [
                            {
                              "type": "output_text",
                              "text": "Hello! How can I help you?",
                              "annotations": []
                            }
                          ]
                        }
                      ],
                      "usage": {
                        "input_tokens": 8,
                        "output_tokens": 11,
                        "total_tokens": 19,
                        "output_tokens_details": {
                          "reasoning_tokens": 0
                        }
                      },
                      "error": null
                    }
                  },
                  "reasoning": {
                    "summary": "Reasoning",
                    "value": {
                      "id": "resp_EXAMPLE",
                      "object": "response",
                      "created_at": 1790222400,
                      "status": "completed",
                      "model": "gpt-6-astra",
                      "output": [
                        {
                          "type": "reasoning",
                          "id": "rs_EXAMPLE",
                          "summary": []
                        },
                        {
                          "type": "message",
                          "id": "msg_EXAMPLE",
                          "role": "assistant",
                          "status": "completed",
                          "content": [
                            {
                              "type": "output_text",
                              "text": "Suppose √2 = p/q in lowest terms... therefore √2 is irrational.",
                              "annotations": []
                            }
                          ]
                        }
                      ],
                      "usage": {
                        "input_tokens": 15,
                        "output_tokens": 1204,
                        "total_tokens": 1219,
                        "output_tokens_details": {
                          "reasoning_tokens": 896
                        }
                      },
                      "error": null
                    }
                  },
                  "tools": {
                    "summary": "Tool calls",
                    "value": {
                      "id": "resp_EXAMPLE",
                      "object": "response",
                      "created_at": 1790222400,
                      "status": "completed",
                      "model": "gpt-5.6-sol",
                      "output": [
                        {
                          "type": "function_call",
                          "id": "fc_EXAMPLE",
                          "call_id": "call_EXAMPLE",
                          "name": "get_weather",
                          "arguments": "{\"city\":\"Shanghai\"}",
                          "status": "completed"
                        }
                      ],
                      "usage": {
                        "input_tokens": 52,
                        "output_tokens": 18,
                        "total_tokens": 70,
                        "output_tokens_details": {
                          "reasoning_tokens": 0
                        }
                      },
                      "error": null
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Unreadable request body or missing fields",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or expired API key (`missing_api_key` / `invalid_api_key` / `api_key_expired`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Balance, or key / member / department quota, exhausted (`insufficient_quota`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "The model is not in this key's group (`model_not_found`), or the path does not belong to the group (`route_not_found`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "Request body over 60 MB (`request_too_large`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Account or key concurrency cap reached (`user_concurrency_limit` / `apikey_concurrency_limit`), with `Retry-After`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "If the message says the stateful session \"can no longer be resumed\", drop `previous_response_id` and start a new conversation",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-hopbase-slug": "responses",
        "x-hopbase-summary": "OpenAI Responses API: used by Codex CLI and by GPT, GLM, Qwen, Grok and other models; stateless, so send the full history every turn.",
        "x-hopbase-docs": "https://hop-base.com/zh-cn/docs/api-reference/responses",
        "x-hopbase-scenarios": [
          {
            "id": "text",
            "label": "Text",
            "request": {
              "body": {
                "model": "gpt-5.6-sol",
                "input": "Hello"
              }
            },
            "response": {
              "status": 200,
              "body": {
                "id": "resp_EXAMPLE",
                "object": "response",
                "created_at": 1790222400,
                "status": "completed",
                "model": "gpt-5.6-sol",
                "output": [
                  {
                    "type": "message",
                    "id": "msg_EXAMPLE",
                    "role": "assistant",
                    "status": "completed",
                    "content": [
                      {
                        "type": "output_text",
                        "text": "Hello! How can I help you?",
                        "annotations": []
                      }
                    ]
                  }
                ],
                "usage": {
                  "input_tokens": 8,
                  "output_tokens": 11,
                  "total_tokens": 19,
                  "output_tokens_details": {
                    "reasoning_tokens": 0
                  }
                },
                "error": null
              }
            }
          },
          {
            "id": "stream",
            "label": "Streaming",
            "request": {
              "stream": true,
              "body": {
                "model": "gpt-5.6-sol",
                "input": "Introduce yourself in three sentences",
                "stream": true
              }
            },
            "response": {
              "status": 200,
              "contentType": "text/event-stream",
              "text": "event: response.created\ndata: {\"type\":\"response.created\",\"response\":{\"id\":\"resp_EXAMPLE\",\"status\":\"in_progress\",\"model\":\"gpt-5.6-sol\"}}\n\nevent: response.output_text.delta\ndata: {\"type\":\"response.output_text.delta\",\"item_id\":\"msg_EXAMPLE\",\"output_index\":0,\"content_index\":0,\"delta\":\"I am\"}\n\n: hopbase-keepalive\n\nevent: response.output_text.done\ndata: {\"type\":\"response.output_text.done\",\"item_id\":\"msg_EXAMPLE\",\"output_index\":0,\"content_index\":0,\"text\":\"I am an AI assistant. ...\"}\n\nevent: response.completed\ndata: {\"type\":\"response.completed\",\"response\":{\"id\":\"resp_EXAMPLE\",\"status\":\"completed\",\"usage\":{\"input_tokens\":14,\"output_tokens\":58,\"total_tokens\":72}}}"
            }
          },
          {
            "id": "reasoning",
            "label": "Reasoning",
            "request": {
              "body": {
                "model": "gpt-6-astra",
                "input": "Prove that the square root of 2 is irrational",
                "reasoning": {
                  "effort": "high"
                }
              }
            },
            "response": {
              "status": 200,
              "body": {
                "id": "resp_EXAMPLE",
                "object": "response",
                "created_at": 1790222400,
                "status": "completed",
                "model": "gpt-6-astra",
                "output": [
                  {
                    "type": "reasoning",
                    "id": "rs_EXAMPLE",
                    "summary": []
                  },
                  {
                    "type": "message",
                    "id": "msg_EXAMPLE",
                    "role": "assistant",
                    "status": "completed",
                    "content": [
                      {
                        "type": "output_text",
                        "text": "Suppose √2 = p/q in lowest terms... therefore √2 is irrational.",
                        "annotations": []
                      }
                    ]
                  }
                ],
                "usage": {
                  "input_tokens": 15,
                  "output_tokens": 1204,
                  "total_tokens": 1219,
                  "output_tokens_details": {
                    "reasoning_tokens": 896
                  }
                },
                "error": null
              }
            }
          },
          {
            "id": "tools",
            "label": "Tool calls",
            "request": {
              "body": {
                "model": "gpt-5.6-sol",
                "input": "What's the weather in Shanghai today?",
                "tools": [
                  {
                    "type": "function",
                    "name": "get_weather",
                    "description": "Get the weather for a city",
                    "parameters": {
                      "type": "object",
                      "properties": {
                        "city": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "city"
                      ]
                    }
                  }
                ]
              }
            },
            "response": {
              "status": 200,
              "body": {
                "id": "resp_EXAMPLE",
                "object": "response",
                "created_at": 1790222400,
                "status": "completed",
                "model": "gpt-5.6-sol",
                "output": [
                  {
                    "type": "function_call",
                    "id": "fc_EXAMPLE",
                    "call_id": "call_EXAMPLE",
                    "name": "get_weather",
                    "arguments": "{\"city\":\"Shanghai\"}",
                    "status": "completed"
                  }
                ],
                "usage": {
                  "input_tokens": 52,
                  "output_tokens": 18,
                  "total_tokens": 70,
                  "output_tokens_details": {
                    "reasoning_tokens": 0
                  }
                },
                "error": null
              }
            }
          }
        ],
        "x-hopbase-related": [
          {
            "label": "Codex CLI",
            "href": "/docs/tools/codex-cli"
          },
          {
            "label": "OpenAI SDK integration",
            "href": "/docs/protocols/openai-sdk"
          },
          {
            "label": "Streaming events",
            "href": "/docs/api-reference/streaming-events"
          }
        ],
        "x-hopbase-sources": [
          "content/docs/protocols/openai-sdk.zh-cn.mdx#支持的请求参数",
          "content/docs/reference/base-url.zh-cn.mdx",
          "content/docs/protocols/qwen.zh-cn.mdx#网关会改动请求的一处",
          "content/docs/tools/codex-cli.zh-cn.mdx"
        ]
      }
    },
    "/v1/messages": {
      "post": {
        "operationId": "createMessage",
        "summary": "Create message",
        "description": "Claude models use the Anthropic protocol. Set the SDK Base URL to `https://api.hop-base.com` (**without** `/v1`); the request path is still `/v1/messages`. `POST /v1/messages/count_tokens` is also supported.\n\nThe table lists only the parts the gateway fills in or handles specially; other Messages API fields are forwarded as-is, with ranges per Anthropic's official spec. A Claude key calling an OpenAI protocol path returns 404 \"The current platform does not support this API path\".",
        "tags": [
          "Chat"
        ],
        "security": [
          {
            "bearer": []
          },
          {
            "apiKey": []
          }
        ],
        "parameters": [
          {
            "name": "anthropic-version",
            "in": "header",
            "required": false,
            "description": "Added automatically by the SDK and forwarded as-is, e.g. `2023-06-01`",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "anthropic-beta",
            "in": "header",
            "required": false,
            "description": "Beta feature flags, forwarded as-is",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "",
                "properties": {
                  "model": {
                    "type": "string",
                    "description": "A Claude model ID in the current key's group; if the group does not include the model, returns 404 `model_not_found`"
                  },
                  "max_tokens": {
                    "type": "integer",
                    "description": "No gateway cap; the maximum follows the model's official spec. The official API requires it; HopBase fills in 4096 when it is missing, so long outputs are cut off at 4096 (`stop_reason: \"max_tokens\"`). Set it explicitly",
                    "default": 4096
                  },
                  "messages": {
                    "type": "array",
                    "description": "In Anthropic's official format, forwarded as-is",
                    "items": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "role": {
                          "type": "string",
                          "description": "`user` or `assistant`"
                        },
                        "content": {
                          "description": "A string, or an array of content blocks (`text`, `image`, `tool_use`, `tool_result`, etc.)",
                          "anyOf": [
                            {
                              "type": "string"
                            },
                            {
                              "type": "array"
                            }
                          ]
                        }
                      },
                      "required": [
                        "role",
                        "content"
                      ]
                    },
                    "minItems": 1
                  },
                  "system": {
                    "description": "System prompt, forwarded as-is",
                    "anyOf": [
                      {
                        "type": "string"
                      },
                      {
                        "type": "array"
                      }
                    ]
                  },
                  "stream": {
                    "type": "boolean",
                    "description": "`true` returns an Anthropic SSE event stream",
                    "default": false
                  },
                  "tools": {
                    "type": "array",
                    "description": "Anthropic tool definitions (`name`, `description`, `input_schema`), forwarded as-is",
                    "items": {
                      "type": "object"
                    }
                  },
                  "thinking": {
                    "type": "object",
                    "description": "Extended thinking config, forwarded as-is; values per Anthropic's official spec"
                  },
                  "temperature": {
                    "type": "number",
                    "description": "Forwarded as-is; range per Anthropic's official spec"
                  }
                },
                "required": [
                  "model",
                  "messages"
                ],
                "additionalProperties": true
              },
              "examples": {
                "text": {
                  "summary": "Text",
                  "value": {
                    "model": "claude-sonnet-5",
                    "max_tokens": 1024,
                    "messages": [
                      {
                        "role": "user",
                        "content": "Hello"
                      }
                    ]
                  }
                },
                "stream": {
                  "summary": "Streaming",
                  "value": {
                    "model": "claude-sonnet-5",
                    "max_tokens": 1024,
                    "stream": true,
                    "messages": [
                      {
                        "role": "user",
                        "content": "Hello"
                      }
                    ]
                  }
                },
                "tools": {
                  "summary": "Tool calls",
                  "value": {
                    "model": "claude-sonnet-5",
                    "max_tokens": 1024,
                    "tools": [
                      {
                        "name": "get_weather",
                        "description": "Get the weather for a city",
                        "input_schema": {
                          "type": "object",
                          "properties": {
                            "city": {
                              "type": "string"
                            }
                          },
                          "required": [
                            "city"
                          ]
                        }
                      }
                    ],
                    "messages": [
                      {
                        "role": "user",
                        "content": "What's the weather in Shanghai today?"
                      }
                    ]
                  }
                },
                "system": {
                  "summary": "System prompt",
                  "value": {
                    "model": "claude-opus-5-5",
                    "max_tokens": 2048,
                    "system": "You are a meticulous code reviewer. Point out only issues you are certain of.",
                    "messages": [
                      {
                        "role": "user",
                        "content": "Review this code: for i in range(len(xs)): print(xs[i+1])"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Success. Non-streaming returns `message` JSON; with `stream: true` it returns Anthropic SSE",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "`message` object",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "Message ID"
                    },
                    "type": {
                      "const": "message"
                    },
                    "role": {
                      "const": "assistant"
                    },
                    "model": {
                      "type": "string",
                      "description": "Model ID"
                    },
                    "content": {
                      "type": "array",
                      "description": "Content blocks",
                      "items": {
                        "type": "object",
                        "description": "",
                        "properties": {
                          "type": {
                            "type": "string",
                            "description": "`text` / `thinking` / `tool_use`"
                          },
                          "text": {
                            "type": "string",
                            "description": "Text of a `text` block"
                          },
                          "name": {
                            "type": "string",
                            "description": "`tool_use`: tool name"
                          },
                          "input": {
                            "type": "object",
                            "description": "`tool_use`: tool input"
                          }
                        }
                      }
                    },
                    "stop_reason": {
                      "type": "string",
                      "description": "`end_turn` / `max_tokens` / `tool_use` / `stop_sequence`"
                    },
                    "usage": {
                      "type": "object",
                      "description": "Token usage",
                      "properties": {
                        "input_tokens": {
                          "type": "integer",
                          "description": "Input tokens"
                        },
                        "output_tokens": {
                          "type": "integer",
                          "description": "Output tokens"
                        },
                        "cache_creation_input_tokens": {
                          "type": "integer",
                          "description": "Input tokens written to the cache"
                        },
                        "cache_read_input_tokens": {
                          "type": "integer",
                          "description": "Input tokens read from the cache"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "text": {
                    "summary": "Text",
                    "value": {
                      "id": "msg_EXAMPLE",
                      "type": "message",
                      "role": "assistant",
                      "model": "claude-sonnet-5",
                      "content": [
                        {
                          "type": "text",
                          "text": "Hello! How can I help you?"
                        }
                      ],
                      "stop_reason": "end_turn",
                      "stop_sequence": null,
                      "usage": {
                        "input_tokens": 9,
                        "output_tokens": 14,
                        "cache_creation_input_tokens": 0,
                        "cache_read_input_tokens": 0
                      }
                    }
                  },
                  "tools": {
                    "summary": "Tool calls",
                    "value": {
                      "id": "msg_EXAMPLE",
                      "type": "message",
                      "role": "assistant",
                      "model": "claude-sonnet-5",
                      "content": [
                        {
                          "type": "text",
                          "text": "Let me check the weather in Shanghai."
                        },
                        {
                          "type": "tool_use",
                          "id": "toolu_EXAMPLE",
                          "name": "get_weather",
                          "input": {
                            "city": "Shanghai"
                          }
                        }
                      ],
                      "stop_reason": "tool_use",
                      "stop_sequence": null,
                      "usage": {
                        "input_tokens": 402,
                        "output_tokens": 58,
                        "cache_creation_input_tokens": 0,
                        "cache_read_input_tokens": 0
                      }
                    }
                  },
                  "system": {
                    "summary": "System prompt",
                    "value": {
                      "id": "msg_EXAMPLE",
                      "type": "message",
                      "role": "assistant",
                      "model": "claude-opus-5-5",
                      "content": [
                        {
                          "type": "text",
                          "text": "Out of bounds: on the last iteration `xs[i+1]` raises IndexError. Use `for x in xs[1:]: print(x)` instead."
                        }
                      ],
                      "stop_reason": "end_turn",
                      "stop_sequence": null,
                      "usage": {
                        "input_tokens": 48,
                        "output_tokens": 41,
                        "cache_creation_input_tokens": 0,
                        "cache_read_input_tokens": 0
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Anthropic shape: `{\"type\":\"error\",\"error\":{\"type\":\"invalid_request_error\",\"message\":\"…\"}}`, with no `code`. Key-validation errors (401, 402, 403) still use the OpenAI shape",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "",
                  "properties": {
                    "type": {
                      "const": "error"
                    },
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "type": {
                          "type": "string",
                          "description": "Error type"
                        },
                        "message": {
                          "type": "string",
                          "description": "Error message"
                        }
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or expired API key (`missing_api_key` / `invalid_api_key` / `api_key_expired`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Balance, or key / member / department quota, exhausted (`insufficient_quota`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "The model is not in this key's group (`model_not_found`), or the path does not belong to the group (`route_not_found`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "Request body over 60 MB (`request_too_large`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Account or key concurrency cap reached (`user_concurrency_limit` / `apikey_concurrency_limit`), with `Retry-After`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-hopbase-slug": "messages",
        "x-hopbase-summary": "Anthropic Messages API: for Claude models only; the Base URL has no /v1, and the Anthropic SDK and Claude Code work directly.",
        "x-hopbase-docs": "https://hop-base.com/zh-cn/docs/api-reference/messages",
        "x-hopbase-scenarios": [
          {
            "id": "text",
            "label": "Text",
            "request": {
              "body": {
                "model": "claude-sonnet-5",
                "max_tokens": 1024,
                "messages": [
                  {
                    "role": "user",
                    "content": "Hello"
                  }
                ]
              }
            },
            "response": {
              "status": 200,
              "body": {
                "id": "msg_EXAMPLE",
                "type": "message",
                "role": "assistant",
                "model": "claude-sonnet-5",
                "content": [
                  {
                    "type": "text",
                    "text": "Hello! How can I help you?"
                  }
                ],
                "stop_reason": "end_turn",
                "stop_sequence": null,
                "usage": {
                  "input_tokens": 9,
                  "output_tokens": 14,
                  "cache_creation_input_tokens": 0,
                  "cache_read_input_tokens": 0
                }
              }
            }
          },
          {
            "id": "stream",
            "label": "Streaming",
            "request": {
              "stream": true,
              "body": {
                "model": "claude-sonnet-5",
                "max_tokens": 1024,
                "stream": true,
                "messages": [
                  {
                    "role": "user",
                    "content": "Hello"
                  }
                ]
              }
            },
            "response": {
              "status": 200,
              "contentType": "text/event-stream",
              "text": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"id\":\"msg_EXAMPLE\",\"type\":\"message\",\"role\":\"assistant\",\"model\":\"claude-sonnet-5\",\"content\":[],\"usage\":{\"input_tokens\":9,\"output_tokens\":1}}}\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Hello!\"}}\n\n: hopbase-keepalive\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\"},\"usage\":{\"output_tokens\":14}}\n\nevent: message_stop\ndata: {\"type\":\"message_stop\"}"
            }
          },
          {
            "id": "tools",
            "label": "Tool calls",
            "request": {
              "body": {
                "model": "claude-sonnet-5",
                "max_tokens": 1024,
                "tools": [
                  {
                    "name": "get_weather",
                    "description": "Get the weather for a city",
                    "input_schema": {
                      "type": "object",
                      "properties": {
                        "city": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "city"
                      ]
                    }
                  }
                ],
                "messages": [
                  {
                    "role": "user",
                    "content": "What's the weather in Shanghai today?"
                  }
                ]
              }
            },
            "response": {
              "status": 200,
              "body": {
                "id": "msg_EXAMPLE",
                "type": "message",
                "role": "assistant",
                "model": "claude-sonnet-5",
                "content": [
                  {
                    "type": "text",
                    "text": "Let me check the weather in Shanghai."
                  },
                  {
                    "type": "tool_use",
                    "id": "toolu_EXAMPLE",
                    "name": "get_weather",
                    "input": {
                      "city": "Shanghai"
                    }
                  }
                ],
                "stop_reason": "tool_use",
                "stop_sequence": null,
                "usage": {
                  "input_tokens": 402,
                  "output_tokens": 58,
                  "cache_creation_input_tokens": 0,
                  "cache_read_input_tokens": 0
                }
              }
            }
          },
          {
            "id": "system",
            "label": "System prompt",
            "request": {
              "body": {
                "model": "claude-opus-5-5",
                "max_tokens": 2048,
                "system": "You are a meticulous code reviewer. Point out only issues you are certain of.",
                "messages": [
                  {
                    "role": "user",
                    "content": "Review this code: for i in range(len(xs)): print(xs[i+1])"
                  }
                ]
              }
            },
            "response": {
              "status": 200,
              "body": {
                "id": "msg_EXAMPLE",
                "type": "message",
                "role": "assistant",
                "model": "claude-opus-5-5",
                "content": [
                  {
                    "type": "text",
                    "text": "Out of bounds: on the last iteration `xs[i+1]` raises IndexError. Use `for x in xs[1:]: print(x)` instead."
                  }
                ],
                "stop_reason": "end_turn",
                "stop_sequence": null,
                "usage": {
                  "input_tokens": 48,
                  "output_tokens": 41,
                  "cache_creation_input_tokens": 0,
                  "cache_read_input_tokens": 0
                }
              }
            }
          }
        ],
        "x-hopbase-related": [
          {
            "label": "Anthropic SDK integration",
            "href": "/docs/protocols/anthropic-sdk"
          },
          {
            "label": "Claude Code",
            "href": "/docs/tools/claude-code"
          },
          {
            "label": "Streaming events",
            "href": "/docs/api-reference/streaming-events"
          }
        ],
        "x-hopbase-sources": [
          "content/docs/protocols/anthropic-sdk.zh-cn.mdx#支持的请求参数",
          "content/docs/protocols/curl.zh-cn.mdx",
          "content/docs/reference/errors.zh-cn.mdx#错误响应结构"
        ]
      }
    },
    "/v1/images/generations": {
      "post": {
        "operationId": "createImage",
        "summary": "Create image",
        "description": "Generates images from a prompt. GPT Image and Gemini return `data[].b64_json`; Seedream returns `data[].url` (valid for 24 hours). Seedream and the two Gemini groups also do image-to-image on this endpoint via `image` / `images`.\n\n**Parameters and limits differ by model**: select a model below and the parameter table switches with it. The numbers come from the specs exported by the plugins' validation code (the same source as `/spec/models/<model>.json`). When GPT Image generation takes longer than about 40 seconds, the server sends 200 first and writes whitespace keep-alives, so a later failure is still a 200. Decide success by whether the response body contains `error`, and set the client read timeout to at least 300 seconds.\n\nKling and Midjourney are also submitted on this endpoint, but always asynchronously (202 + `id`; poll with [Get video task](https://hop-base.com/zh-cn/docs/api-reference/video-task)). Select \"Kling\" or \"Midjourney\" in the model picker to see them. For Grok Imagine, see [Grok Imagine image generation](https://hop-base.com/zh-cn/docs/media/grok-image).\n\n- GPT Image does not support the official streaming field `partial_images`; omit it. `stream: true` returns HopBase Images SSE, not per-image preview events.\n- `output_compression`, `moderation`, `user` and `response_format` are passed through only in synchronous text-to-image JSON and synchronous multipart edits; **JSON edits and async tasks do not keep these fields**. GPT Image async keeps only `model`, `prompt`, `n`, `size`, `quality`, `background`, `output_format`, `input_fidelity` and the images / mask used for editing.\n- Gemini billing: \"Gemini (all models, incl. image)\" is billed a flat price per image (same for 1K / 2K / 4K); \"Gemini Official Direct\" is billed by tokens (output tokens × price).\n- The Chat Completions to Images bridge keeps only the first 6 reference images; to use 14, call this endpoint directly.",
        "tags": [
          "Images"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "Prefer",
            "in": "header",
            "required": false,
            "description": "`respond-async`: GPT Image / Gemini immediately return `202 Accepted` with `task_id` and `status_url`; then poll `GET /v1/images/tasks?task_id=…`. Recommended for large 2K / 4K images. Seedream ignores this header and returns synchronously as usual",
            "schema": {
              "type": "string",
              "enum": [
                "respond-async"
              ]
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "https://hop-base.com/spec/models/gpt-image-2.json"
                  },
                  {
                    "$ref": "https://hop-base.com/spec/models/gpt-image-2.5-flare.json"
                  },
                  {
                    "$ref": "https://hop-base.com/spec/models/gpt-image-2.5-sunburst.json"
                  },
                  {
                    "$ref": "https://hop-base.com/spec/models/gemini-3.1-flash-image.json"
                  },
                  {
                    "$ref": "https://hop-base.com/spec/models/gemini-3.1-flash-image-preview.json"
                  },
                  {
                    "$ref": "https://hop-base.com/spec/models/gemini-3-pro-image.json"
                  },
                  {
                    "$ref": "https://hop-base.com/spec/models/gemini-3.1-flash-lite-image.json"
                  },
                  {
                    "$ref": "https://hop-base.com/spec/models/gemini-2.5-flash-image.json"
                  },
                  {
                    "$ref": "https://hop-base.com/spec/models/seedream-5-0-pro.json"
                  },
                  {
                    "$ref": "https://hop-base.com/spec/models/seedream-5-0-lite.json"
                  },
                  {
                    "$ref": "https://hop-base.com/spec/models/seedream-4-5.json"
                  },
                  {
                    "type": "object",
                    "description": "",
                    "properties": {
                      "model": {
                        "type": "string",
                        "description": "Kling image model ID; a video model ID returns 400",
                        "enum": [
                          "kling-image-expand",
                          "kling-image-o1",
                          "kling-image-v2-1",
                          "kling-image-v2-1-i2i",
                          "kling-image-v2-1-multi-ref",
                          "kling-image-v3",
                          "kling-image-v3-omni"
                        ]
                      },
                      "prompt": {
                        "type": "string",
                        "description": "Provide this and/or a non-empty `images`"
                      },
                      "quality": {
                        "type": "string",
                        "description": "Case-insensitive; OpenAI-style values such as `high` or `standard` are rejected. Tiers per model: `kling-image-v3` 1k / 2k; `kling-image-v3-omni` 1k / 2k / 4k; `kling-image-o1` 1k / 2k / 4k; `kling-image-v2-1` 1k / 2k; `kling-image-v2-1-i2i` 1k / 2k; `kling-image-v2-1-multi-ref` 1k / 2k; `kling-image-expand` 1k",
                        "enum": [
                          "1k",
                          "2k",
                          "4k"
                        ],
                        "default": "1k"
                      },
                      "n": {
                        "type": "integer",
                        "description": "Billed per image actually produced",
                        "minimum": 1,
                        "maximum": 9,
                        "default": 1
                      },
                      "images": {
                        "type": "array",
                        "description": "Reference images; each item has either `url` (public HTTP(S) address) or `file_id`, not both, and must not carry `usage`. `file_id` must be a Kling asset available to the current key, not a Seedance asset ID. Counts: `kling-image-v3` 0–1; `kling-image-v3-omni` 0–10; `kling-image-o1` 0–10; `kling-image-v2-1` none accepted; `kling-image-v2-1-i2i` exactly 1; `kling-image-v2-1-multi-ref` 2–4; `kling-image-expand` exactly 1",
                        "items": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "url": {
                              "type": "string",
                              "description": "Public HTTP(S) URL"
                            },
                            "file_id": {
                              "type": "string",
                              "description": "Kling asset ID; use either this or `url`"
                            }
                          }
                        }
                      },
                      "extra": {
                        "type": "object",
                        "description": "Image expansion `kling-image-expand` only: all four ratios are numbers from 0 to 2, omitted means 0, and they cannot all be 0. The expanded area must not exceed 3x the original: (1+left+right) × (1+top+bottom) ≤ 3. A non-empty `extra` on other models returns 400",
                        "properties": {
                          "left_expansion_ratio": {
                            "type": "number",
                            "description": "Expansion ratio",
                            "minimum": 0,
                            "maximum": 2
                          },
                          "right_expansion_ratio": {
                            "type": "number",
                            "description": "Expansion ratio",
                            "minimum": 0,
                            "maximum": 2
                          },
                          "up_expansion_ratio": {
                            "type": "number",
                            "description": "Expansion ratio",
                            "minimum": 0,
                            "maximum": 2
                          },
                          "down_expansion_ratio": {
                            "type": "number",
                            "description": "Expansion ratio",
                            "minimum": 0,
                            "maximum": 2
                          }
                        }
                      }
                    },
                    "required": [
                      "model"
                    ],
                    "title": "Kling",
                    "additionalProperties": false,
                    "x-hopbase-doc": "/docs/media/kling-image",
                    "x-hopbase-note": "Every Kling image model runs as an async task: submission returns 202 with a top-level `id` (`object` is `image.generation.task`); poll with [Get video task](https://hop-base.com/zh-cn/docs/api-reference/video-task) and read `outputs` when done (valid for 6 hours). Only the fields below are accepted; any other field (such as `size`, `aspect_ratio`, `image`, `mask`, `response_format`, `style`, `user`) returns 400. Kling images reserve no balance and are blocked only when the balance is ≤ 0; a task still unfinished 2 hours after creation is marked failed and not billed."
                  },
                  {
                    "type": "object",
                    "description": "",
                    "properties": {
                      "model": {
                        "const": "midjourney-v8-2",
                        "description": "Exact match"
                      },
                      "prompt": {
                        "type": "string",
                        "description": "Image description, optionally followed by `--` parameters (`--ar` aspect ratio, `--hd` native 2K, `--s`, `--c`, `--weird`, `--iw`, `--sref` + `--sw`, `--no`, `--seed`, `--tile`, `--exp`). A description is required: it cannot be only `--` parameters, and it cannot contain `::`. The `--ar` ratio must not exceed 14:1, or 4:1 with `--hd`. `--q`, `--niji`, `--repeat`, `--oref`, `--cref`, `--stealth`, `--stop`, `--draft` and `--profile` return 400",
                        "minLength": 1
                      },
                      "images": {
                        "type": "array",
                        "description": "Reference image, 0–1 items; each item has either `url` (public absolute HTTP(S) address) or `file_id`, not both, and must not carry `usage`",
                        "items": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "url": {
                              "type": "string",
                              "description": "Public absolute HTTP(S) address"
                            },
                            "file_id": {
                              "type": "string",
                              "description": "Asset ID; use either this or `url`"
                            }
                          }
                        },
                        "maxItems": 1
                      },
                      "n": {
                        "const": 4,
                        "default": 4,
                        "description": "Must be `4`: each task always produces 4 images, billed per image returned"
                      },
                      "quality": {
                        "description": "Omit it: a non-empty value returns 400. For 2K, write `--hd` in the prompt"
                      },
                      "extra": {
                        "description": "Omit it: a non-empty object returns 400"
                      }
                    },
                    "required": [
                      "model",
                      "prompt"
                    ],
                    "title": "Midjourney",
                    "additionalProperties": false,
                    "x-hopbase-doc": "/docs/media/midjourney",
                    "x-hopbase-note": "Async: submission returns 202 with `id` (`images_per_task` and `requested_images` are both `4`; `billing_bucket` shows whether it is priced at the default tier or the `--hd` 2K tier). Poll with [Get video task](https://hop-base.com/zh-cn/docs/api-reference/video-task); when done, `outputs` carries four URLs (valid for 6 hours). The request body is parsed as strict JSON, and any field outside the table (including `size`, `response_format`, `style`, `user`, `background`, `output_format`) returns 400. A task still unfinished 2 hours after creation is marked failed and not billed."
                  }
                ]
              },
              "examples": {
                "gpt": {
                  "summary": "Text-to-image",
                  "value": {
                    "model": "gpt-image-2",
                    "prompt": "A clean product photo of a ceramic mug on a white tabletop",
                    "size": "1024x1024",
                    "quality": "high"
                  }
                },
                "gemini-4k": {
                  "summary": "Gemini 4K",
                  "value": {
                    "model": "gemini-3-pro-image",
                    "prompt": "A ceramic teapot on a sunlit table",
                    "image_size": "4K",
                    "aspect_ratio": "16:9",
                    "n": 2
                  }
                },
                "seedream-ref": {
                  "summary": "Reference image",
                  "value": {
                    "model": "seedream-5-0-pro",
                    "prompt": "Keep the person's pose and replace the background with a snowy mountain sunrise",
                    "image": [
                      "https://example.com/portrait.png"
                    ],
                    "size": "2K",
                    "response_format": "url"
                  }
                },
                "async": {
                  "summary": "Async",
                  "value": {
                    "model": "gpt-image-2",
                    "prompt": "A cinematic futuristic city at night",
                    "size": "2048x2048"
                  }
                },
                "kling": {
                  "summary": "Kling",
                  "value": {
                    "model": "kling-image-v3",
                    "prompt": "A ceramic teapot on a sunlit table",
                    "quality": "1k",
                    "n": 1
                  }
                },
                "midjourney": {
                  "summary": "Midjourney",
                  "value": {
                    "model": "midjourney-v8-2",
                    "prompt": "a lighthouse on a cliff at dawn --ar 16:9 --hd"
                  }
                }
              },
              "x-hopbase-param-docs": {
                "gpt-image": {
                  "model": "First confirm that `GET /v1/models` for the current key includes this ID",
                  "prompt": "Generation or editing instruction; empty returns 400 `prompt must not be empty`. The gateway sets no length limit; the official cap applies",
                  "size": "E.g. `1024x1024`, `2048x2048`, `3840x2160`. Invalid sizes return 400 before generation and are not billed; `1K` / `2K` / `4K` are not accepted",
                  "quality": "Higher tiers produce more output tokens and cost more: at 1024x1024, measured output is about 200 tokens for low, 1,760 for high, 3,120 for xhigh and 7,020 for max",
                  "n": "Some groups support only 1; larger values return 400. Values ≤ 0 are treated as 1",
                  "background": "`transparent` requires `png` or `webp`; transparent backgrounds on 2.0 are a preview capability",
                  "output_format": "Sets the format of the decoded `b64_json`",
                  "output_compression": "`jpeg` / `webp` only; kept only in synchronous generations JSON and multipart edits",
                  "moderation": "Does not turn off content safety checks",
                  "user": "End-user identifier string; not a HopBase account ID, and it does not change billing attribution",
                  "response_format": "Always returned as `b64_json` whatever you pass; you cannot get a download link via `url`, so omit it",
                  "stream": "`true` switches to HopBase Images SSE (keepalives are sent meanwhile; only the last `data:` event is the Images JSON, ending with `[DONE]`), not OpenAI's native per-image preview events. Keep it `false` in SDKs",
                  "input_fidelity": "Compatibility field; GPT Image 2 processes reference images at high fidelity by default, so omit it",
                  "image": "Multipart files (`image` / `image[]`), or in JSON an HTTP(S) URL / Data URL string or array of strings. `images` is not read; raw base64 and `file_id` are not accepted; images may be compressed before forwarding",
                  "mask": "Transparent areas mark what to edit; the gateway scales the mask to the size of the first reference image. Pixels outside the mask are not guaranteed to stay identical"
                },
                "gemini-image": {
                  "model": "`GET /v1/models` for the current key is authoritative",
                  "prompt": "If the model refuses or replies with text only, returns 400 (the message quotes that text) or 502: rephrase the prompt",
                  "size": "`WxH` is never rejected for its ratio: it maps to the closest official ratio, and the tier is derived from the long edge and **silently lowered to the model's highest tier**. An explicit `1K` / `2K` / `4K` above the model's tier returns 400; if `image_size` is also sent, it wins",
                  "n": "Generated in parallel. All or nothing: if any image fails, the whole request fails and is not billed",
                  "image_size": "Flat top-level form, equivalent to `google.image_config.image_size`; overrides the tier derived from `size`",
                  "aspect_ratio": "Flat top-level form, equivalent to `google.image_config.aspect_ratio`; takes precedence over `size`",
                  "google": "In SDKs it can be written as `extra_body.google.image_config`; all three forms are equivalent",
                  "image": "Reference images, placed directly in the generations request body; if both are sent, `images` wins. On \"Gemini Official Direct\" each image must be ≤ 20 MiB decoded, and there is no `/v1/images/edits`",
                  "images": "Same as `image`; if both are sent, `images` wins",
                  "mask": "Not supported: sending `mask` returns 400; describe the region to change in the prompt instead",
                  "background": "`transparent` is not supported (returns 400)",
                  "stream": "Not supported; omit it or pass `false`"
                },
                "seedream": {
                  "model": "Use the full ID returned by `GET /v1/models` for the current key",
                  "prompt": "Image content, composition, style or editing instruction; for local edits you can describe coordinates, a bbox, arrows or areas drawn on the reference image",
                  "size": "Invalid values return 400 before generation with the valid range, and are not billed",
                  "n": "Other values (including `null`) return 400",
                  "response_format": "Returns a signed direct link valid for 24 hours",
                  "output_format": "`jpeg` only on 4.5",
                  "optimize_prompt_options": "Must be an object",
                  "image": "Passing it triggers single- or multi-image image-to-image or editing; `/v1/images/edits` requires at least 1. URLs are not downloaded or size-checked at submission",
                  "watermark": "Always `false` server-side",
                  "mask": "Not supported: `/v1/images/edits` with `mask` returns 400 (`null` too)"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Synchronous success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Synchronous success (with `Prefer: respond-async` it is 202 with `task_id`; see below)",
                  "properties": {
                    "created": {
                      "type": "integer",
                      "description": "Unix seconds"
                    },
                    "data": {
                      "type": "array",
                      "description": "One entry per image",
                      "items": {
                        "type": "object",
                        "description": "",
                        "properties": {
                          "b64_json": {
                            "type": "string",
                            "description": "GPT Image / Gemini: Base64 image data; save it after decoding according to `output_format`. Gemini may return JPEG, so check `mime_type`"
                          },
                          "url": {
                            "type": "string",
                            "description": "Seedream: signed direct link valid for 24 hours; once expired, the only option is to regenerate"
                          },
                          "mime_type": {
                            "type": "string",
                            "description": "Image MIME type"
                          },
                          "revised_prompt": {
                            "type": "string",
                            "description": "Prompt as rewritten by the model (some models)"
                          }
                        }
                      }
                    },
                    "usage": {
                      "type": "object",
                      "description": "May be returned",
                      "properties": {
                        "input_tokens": {
                          "type": "integer",
                          "description": "Input tokens"
                        },
                        "output_tokens": {
                          "type": "integer",
                          "description": "Output tokens"
                        },
                        "total_tokens": {
                          "type": "integer",
                          "description": "Total"
                        }
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "examples": {
                  "gpt": {
                    "summary": "Text-to-image",
                    "value": {
                      "created": 1790222400,
                      "data": [
                        {
                          "b64_json": "iVBORw0KGgoAAA..."
                        }
                      ],
                      "usage": {
                        "input_tokens": 42,
                        "output_tokens": 1760,
                        "total_tokens": 1802
                      }
                    }
                  },
                  "gemini-4k": {
                    "summary": "Gemini 4K",
                    "value": {
                      "data": [
                        {
                          "b64_json": "/9j/4AAQSkZJRg...",
                          "mime_type": "image/jpeg"
                        },
                        {
                          "b64_json": "/9j/4AAQSkZJRg...",
                          "mime_type": "image/jpeg"
                        }
                      ]
                    }
                  },
                  "seedream-ref": {
                    "summary": "Reference image",
                    "value": {
                      "created": 1790222400,
                      "data": [
                        {
                          "url": "https://example.com/generated-image.png"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "Accepted asynchronously: GPT Image / Gemini with `Prefer: respond-async`; always for Kling and Midjourney",
            "content": {
              "application/json": {
                "schema": {
                  "anyOf": [
                    {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "task_id": {
                          "type": "string",
                          "description": "Task ID"
                        },
                        "status": {
                          "type": "string",
                          "description": "`pending`"
                        },
                        "status_url": {
                          "type": "string",
                          "description": "Polling URL: `GET /v1/images/tasks?task_id=…` (putting the task ID in the path is not supported)"
                        }
                      },
                      "title": "GPT Image / Gemini"
                    },
                    {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "Task ID; query it with `GET /v1/video/tasks/{task_id}`"
                        },
                        "object": {
                          "const": "image.generation.task"
                        },
                        "model": {
                          "type": "string",
                          "description": "Model ID"
                        },
                        "status": {
                          "type": "string",
                          "description": "`queued`"
                        },
                        "created": {
                          "type": "integer",
                          "description": "Unix seconds"
                        },
                        "billing_bucket": {
                          "type": "string",
                          "description": "Midjourney: whether it is priced at the default tier or the `--hd` 2K tier"
                        },
                        "requested_images": {
                          "type": "integer",
                          "description": "Number of images produced (always 4 for Midjourney)"
                        },
                        "images_per_task": {
                          "type": "integer",
                          "description": "Midjourney: images per task, always 4"
                        },
                        "notice": {
                          "type": "string",
                          "description": "Midjourney: note that 4 images are always produced and each is billed"
                        }
                      },
                      "title": "Kling / Midjourney"
                    }
                  ]
                },
                "examples": {
                  "async": {
                    "summary": "Async",
                    "value": {
                      "task_id": "imgtask_EXAMPLE",
                      "status": "pending",
                      "status_url": "/v1/images/tasks?task_id=imgtask_EXAMPLE"
                    }
                  },
                  "kling": {
                    "summary": "Kling",
                    "value": {
                      "id": "ktEXAMPLE",
                      "object": "image.generation.task",
                      "status": "queued",
                      "model": "kling-image-v3",
                      "requested_images": 1
                    }
                  },
                  "midjourney": {
                    "summary": "Midjourney",
                    "value": {
                      "id": "ktEXAMPLE",
                      "object": "image.generation.task",
                      "model": "midjourney-v8-2",
                      "status": "queued",
                      "created": 1790000000,
                      "billing_bucket": "img_1k",
                      "requested_images": 4,
                      "images_per_task": 4,
                      "notice": "this model always returns 4 images per task and bills every returned image"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid parameters (rejected before generation, not billed); content safety block `safety_rejected`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or expired API key (`missing_api_key` / `invalid_api_key` / `api_key_expired`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Balance, or key / member / department quota, exhausted (`insufficient_quota`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "The model is not in this key's group (`model_not_found`), or the path does not belong to the group (`route_not_found`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "Request body over 60 MB (`request_too_large`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Account or key concurrency cap reached (`user_concurrency_limit` / `apikey_concurrency_limit`), with `Retry-After`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-hopbase-slug": "images-generations",
        "x-hopbase-summary": "OpenAI Images-compatible text-to-image: GPT Image, Gemini Banana and Seedream; Seedream and Gemini also take reference images here.",
        "x-hopbase-docs": "https://hop-base.com/zh-cn/docs/api-reference/images-generations",
        "x-hopbase-scenarios": [
          {
            "id": "gpt",
            "label": "Text-to-image",
            "request": {
              "body": {
                "model": "gpt-image-2",
                "prompt": "A clean product photo of a ceramic mug on a white tabletop",
                "size": "1024x1024",
                "quality": "high"
              }
            },
            "response": {
              "status": 200,
              "body": {
                "created": 1790222400,
                "data": [
                  {
                    "b64_json": "iVBORw0KGgoAAA..."
                  }
                ],
                "usage": {
                  "input_tokens": 42,
                  "output_tokens": 1760,
                  "total_tokens": 1802
                }
              }
            }
          },
          {
            "id": "gemini-4k",
            "label": "Gemini 4K",
            "request": {
              "body": {
                "model": "gemini-3-pro-image",
                "prompt": "A ceramic teapot on a sunlit table",
                "image_size": "4K",
                "aspect_ratio": "16:9",
                "n": 2
              }
            },
            "response": {
              "status": 200,
              "body": {
                "data": [
                  {
                    "b64_json": "/9j/4AAQSkZJRg...",
                    "mime_type": "image/jpeg"
                  },
                  {
                    "b64_json": "/9j/4AAQSkZJRg...",
                    "mime_type": "image/jpeg"
                  }
                ]
              }
            }
          },
          {
            "id": "seedream-ref",
            "label": "Reference image",
            "request": {
              "body": {
                "model": "seedream-5-0-pro",
                "prompt": "Keep the person's pose and replace the background with a snowy mountain sunrise",
                "image": [
                  "https://example.com/portrait.png"
                ],
                "size": "2K",
                "response_format": "url"
              }
            },
            "response": {
              "status": 200,
              "body": {
                "created": 1790222400,
                "data": [
                  {
                    "url": "https://example.com/generated-image.png"
                  }
                ]
              }
            }
          },
          {
            "id": "async",
            "label": "Async",
            "request": {
              "headers": {
                "Prefer": "respond-async"
              },
              "body": {
                "model": "gpt-image-2",
                "prompt": "A cinematic futuristic city at night",
                "size": "2048x2048"
              }
            },
            "response": {
              "status": 202,
              "body": {
                "task_id": "imgtask_EXAMPLE",
                "status": "pending",
                "status_url": "/v1/images/tasks?task_id=imgtask_EXAMPLE"
              }
            }
          },
          {
            "id": "kling",
            "label": "Kling",
            "request": {
              "body": {
                "model": "kling-image-v3",
                "prompt": "A ceramic teapot on a sunlit table",
                "quality": "1k",
                "n": 1
              }
            },
            "response": {
              "status": 202,
              "body": {
                "id": "ktEXAMPLE",
                "object": "image.generation.task",
                "status": "queued",
                "model": "kling-image-v3",
                "requested_images": 1
              }
            }
          },
          {
            "id": "midjourney",
            "label": "Midjourney",
            "request": {
              "body": {
                "model": "midjourney-v8-2",
                "prompt": "a lighthouse on a cliff at dawn --ar 16:9 --hd"
              }
            },
            "response": {
              "status": 202,
              "body": {
                "id": "ktEXAMPLE",
                "object": "image.generation.task",
                "model": "midjourney-v8-2",
                "status": "queued",
                "created": 1790000000,
                "billing_bucket": "img_1k",
                "requested_images": 4,
                "images_per_task": 4,
                "notice": "this model always returns 4 images per task and bills every returned image"
              }
            }
          }
        ],
        "x-hopbase-related": [
          {
            "label": "Image generation guide",
            "href": "/docs/media/images"
          },
          {
            "label": "Image request builder",
            "href": "/docs/build"
          },
          {
            "label": "Edit image",
            "href": "/docs/api-reference/images-edits"
          }
        ],
        "x-hopbase-sources": [
          "public/spec/models/*.json（scripts/build-model-schemas.mjs，源自 spec/openai.json、spec/gemini.json、spec/seedance.json）",
          "spec/kling.json",
          "content/docs/media/images.zh-cn.mdx",
          "content/docs/media/kling-image.zh-cn.mdx",
          "content/docs/media/midjourney.zh-cn.mdx"
        ],
        "x-hopbase-error-texts": [
          {
            "label": "GPT Image",
            "text": "# size: follow the size rules above\nsize must be WIDTHxHEIGHT or auto\nsize side length exceeds 3840px (4096x2048)\nsize width and height must be multiples of 16 (1000x1000)\nsize aspect ratio must not exceed 3:1 (3840x1024)\nsize total pixel count must be at least 655360 (512x512=262144)\nsize total pixel count must not exceed 8294400 (3840x3840=14745600)\n\n# empty prompt\nprompt must not be empty\n\n# edits JSON: put references in \"image\" as strings or {\"url\": ...}; \"images\" is not read\n/v1/images/edits requires at least one image\nimage object is missing the url field\nimage must be a data URL or an http(s) URL\n\n# remote references: a public URL that returns image/*, at most 25 MiB\nimage download returned HTTP 404\nimage is too large\nimage Content-Type is not image/*: text/html\nreference image URL must not point to an internal address\nimage is too large, please compress it to under 4MB and retry\n\n# content safety (error.code: safety_rejected)\nYour request was rejected by the safety system.\n\n# HTTP 413\nRequest body exceeds the size limit (60 MB)"
          },
          {
            "label": "Gemini",
            "text": "# Gemini (all models, incl. image)\nprompt must not be empty\nn must be between 1 and 10 for model gemini-3-pro-image\nn=3 is too large for 4K output on model gemini-3-pro-image; at most 2 images per request at this size (response size limit); lower n or send separate requests\nmodel gemini-3.1-flash-image does not support tier 4K; supported: 1K, 2K\nmodel gemini-3-pro-image: size \"big\" is not valid; expected WIDTHxHEIGHT (any aspect ratio, mapped to the nearest official tier) or 1K/2K/4K\naspect_ratio \"7:3\" is not supported for model gemini-3-pro-image; allowed values: 1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:9\nimage_size \"4K\" is not supported for model gemini-3.1-flash-image; supported: 1K, 2K\nbackground=transparent is not supported for model gemini-3-pro-image; Gemini image models cannot output transparent images\nmask is not supported for Gemini image models; remove mask and describe the region to edit in the prompt\ntoo many reference images: at most 14 are supported for this model, got 15\n\n# Gemini Official Direct\nmissing prompt\nGemini image generation does not support stream=true; send a non-streaming request\nn must be at most 10\nn=6 is too large for 2K output on model gemini-3.1-flash-image; at most 5 images per request at this size (response size limit); lower n or send separate requests\nImages generations only accepts a JSON request body: ...\nsize 4K is not supported for model gemini-3.1-flash-image; supported tiers: 1K, 2K\nsize \"banana\" is not valid for model gemini-3-pro-image; use auto, WIDTHxHEIGHT (e.g. 1024x1024, mapped to the nearest supported aspect ratio and capped at the model's largest tier), or one of: 1K, 2K, 4K\nimage_config.aspect_ratio \"7:3\" is not supported; allowed values: 1:1, 2:3, 3:2, 3:4, 4:3, 4:5, 5:4, 9:16, 16:9, 21:9\nimage_config.image_size \"4K\" is not supported for model gemini-3.1-flash-image; allowed values: 1K, 2K\nmask is not supported for model gemini-3-pro-image; remove mask and describe the region to edit in the prompt\nbackground=transparent is not supported for model gemini-3-pro-image; Gemini image models cannot output transparent images\nreference image 1: reference image exceeds the 20MB limit\nreference image 1: reference image URL must not point to an internal address\nreference image 1: reference image download returned HTTP 404\nreference image 1: reference file is not a supported image type"
          },
          {
            "label": "Seedream",
            "text": "model seedream-5-0-pro only supports size 1K, 1.5K, 2K or a valid WIDTHxHEIGHT pixel size   # e.g. \"size\": \"auto\"\nmodel seedream-5-0-lite requires the total pixel count of size to be between 3686400 and 16777216\nsize aspect ratio must be between 1:16 and 16:1\nmissing prompt\nresponse_format only supports url\nonly a single output is supported (n=1)\nmodel seedream-4-5 only supports output_format jpeg\noptimize_prompt_options must be an object\nimage must be a URL/data URL string or an array of strings\nevery item in the image array must be a URL or data URL string\nimage must not be empty\nat most 10 reference images are supported\nreference image 1 is invalid: data URL must be base64-encoded\nreference image 1 is invalid: unsupported image format image/svg+xml\nreference image 1 is invalid: a single image must not exceed 30 MB\nimage edits require at least one image reference            # /v1/images/edits without an image\nseedream does not accept a traditional mask; ...            # any \"mask\" on /v1/images/edits, even null"
          }
        ]
      }
    },
    "/v1/images/edits": {
      "post": {
        "operationId": "editImage",
        "summary": "Edit image",
        "description": "Generates from reference images or edits locally. `multipart/form-data` is recommended (local files; reference image field `image` / `image[]`, repeatable); JSON is also accepted (reference images as HTTP(S) URLs or Data URLs). Field names are the same in both. The example on the right uses JSON; for multipart see the [Image generation guide](https://hop-base.com/zh-cn/docs/media/images).\n\nJSON edits and async tasks **do not keep** `output_compression`, `moderation`, `user` or `response_format`. The \"Gemini Official Direct\" group has no such endpoint; pass reference images to [Create image](https://hop-base.com/zh-cn/docs/api-reference/images-generations) instead.",
        "tags": [
          "Images"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "Prefer",
            "in": "header",
            "required": false,
            "description": "`respond-async`: GPT Image / Gemini immediately return `202 Accepted` with `task_id` and `status_url`; then poll `GET /v1/images/tasks?task_id=…`. Recommended for large 2K / 4K images. Seedream ignores this header and returns synchronously as usual",
            "schema": {
              "type": "string",
              "enum": [
                "respond-async"
              ]
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "oneOf": [
                  {
                    "$ref": "https://hop-base.com/spec/models/gpt-image-2.json#/$defs/edits"
                  },
                  {
                    "$ref": "https://hop-base.com/spec/models/gpt-image-2.5-flare.json#/$defs/edits"
                  },
                  {
                    "$ref": "https://hop-base.com/spec/models/gpt-image-2.5-sunburst.json#/$defs/edits"
                  },
                  {
                    "$ref": "https://hop-base.com/spec/models/gemini-3.1-flash-image.json"
                  },
                  {
                    "$ref": "https://hop-base.com/spec/models/gemini-3.1-flash-image-preview.json"
                  },
                  {
                    "$ref": "https://hop-base.com/spec/models/gemini-3-pro-image.json"
                  },
                  {
                    "$ref": "https://hop-base.com/spec/models/gemini-3.1-flash-lite-image.json"
                  },
                  {
                    "$ref": "https://hop-base.com/spec/models/gemini-2.5-flash-image.json"
                  },
                  {
                    "$ref": "https://hop-base.com/spec/models/seedream-5-0-pro.json#/$defs/edits"
                  },
                  {
                    "$ref": "https://hop-base.com/spec/models/seedream-5-0-lite.json#/$defs/edits"
                  },
                  {
                    "$ref": "https://hop-base.com/spec/models/seedream-4-5.json#/$defs/edits"
                  }
                ]
              },
              "examples": {
                "edit": {
                  "summary": "Image-to-image",
                  "value": {
                    "model": "gpt-image-2",
                    "prompt": "Turn the reference image into an oil painting in the style of Van Gogh's The Starry Night",
                    "image": "https://example.com/input.png",
                    "size": "1536x1024",
                    "quality": "medium"
                  }
                },
                "mask": {
                  "summary": "Masked inpainting",
                  "value": {
                    "model": "gpt-image-2.5-flare",
                    "prompt": "Replace the masked area with a vase, styled after the second image",
                    "image": [
                      "https://example.com/scene.png",
                      "https://example.com/style.png"
                    ],
                    "mask": "https://example.com/mask.png",
                    "size": "1024x1024",
                    "quality": "high"
                  }
                },
                "multi": {
                  "summary": "Multiple references",
                  "value": {
                    "model": "seedream-4-5",
                    "prompt": "Place the person from the first image into the scene of the second image, keeping the lighting consistent",
                    "image": [
                      "https://example.com/person.png",
                      "https://example.com/scene.png"
                    ]
                  }
                }
              },
              "x-hopbase-param-docs": {
                "gpt-image": {
                  "model": "First confirm that `GET /v1/models` for the current key includes this ID",
                  "prompt": "Generation or editing instruction; empty returns 400 `prompt must not be empty`. The gateway sets no length limit; the official cap applies",
                  "size": "E.g. `1024x1024`, `2048x2048`, `3840x2160`. Invalid sizes return 400 before generation and are not billed; `1K` / `2K` / `4K` are not accepted",
                  "quality": "Higher tiers produce more output tokens and cost more: at 1024x1024, measured output is about 200 tokens for low, 1,760 for high, 3,120 for xhigh and 7,020 for max",
                  "n": "Some groups support only 1; larger values return 400. Values ≤ 0 are treated as 1",
                  "background": "`transparent` requires `png` or `webp`; transparent backgrounds on 2.0 are a preview capability",
                  "output_format": "Sets the format of the decoded `b64_json`",
                  "output_compression": "`jpeg` / `webp` only; kept only in synchronous generations JSON and multipart edits",
                  "moderation": "Does not turn off content safety checks",
                  "user": "End-user identifier string; not a HopBase account ID, and it does not change billing attribution",
                  "response_format": "Always returned as `b64_json` whatever you pass; you cannot get a download link via `url`, so omit it",
                  "stream": "`true` switches to HopBase Images SSE (keepalives are sent meanwhile; only the last `data:` event is the Images JSON, ending with `[DONE]`), not OpenAI's native per-image preview events. Keep it `false` in SDKs",
                  "input_fidelity": "Compatibility field; GPT Image 2 processes reference images at high fidelity by default, so omit it",
                  "image": "Multipart files (`image` / `image[]`), or in JSON an HTTP(S) URL / Data URL string or array of strings. `images` is not read; raw base64 and `file_id` are not accepted; images may be compressed before forwarding",
                  "mask": "Transparent areas mark what to edit; the gateway scales the mask to the size of the first reference image. Pixels outside the mask are not guaranteed to stay identical"
                },
                "gemini-image": {
                  "model": "`GET /v1/models` for the current key is authoritative",
                  "prompt": "If the model refuses or replies with text only, returns 400 (the message quotes that text) or 502: rephrase the prompt",
                  "size": "`WxH` is never rejected for its ratio: it maps to the closest official ratio, and the tier is derived from the long edge and **silently lowered to the model's highest tier**. An explicit `1K` / `2K` / `4K` above the model's tier returns 400; if `image_size` is also sent, it wins",
                  "n": "Generated in parallel. All or nothing: if any image fails, the whole request fails and is not billed",
                  "image_size": "Flat top-level form, equivalent to `google.image_config.image_size`; overrides the tier derived from `size`",
                  "aspect_ratio": "Flat top-level form, equivalent to `google.image_config.aspect_ratio`; takes precedence over `size`",
                  "google": "In SDKs it can be written as `extra_body.google.image_config`; all three forms are equivalent",
                  "image": "Reference images, placed directly in the generations request body; if both are sent, `images` wins. On \"Gemini Official Direct\" each image must be ≤ 20 MiB decoded, and there is no `/v1/images/edits`",
                  "images": "Same as `image`; if both are sent, `images` wins",
                  "mask": "Not supported: sending `mask` returns 400; describe the region to change in the prompt instead",
                  "background": "`transparent` is not supported (returns 400)",
                  "stream": "Not supported; omit it or pass `false`"
                },
                "seedream": {
                  "model": "Use the full ID returned by `GET /v1/models` for the current key",
                  "prompt": "Image content, composition, style or editing instruction; for local edits you can describe coordinates, a bbox, arrows or areas drawn on the reference image",
                  "size": "Invalid values return 400 before generation with the valid range, and are not billed",
                  "n": "Other values (including `null`) return 400",
                  "response_format": "Returns a signed direct link valid for 24 hours",
                  "output_format": "`jpeg` only on 4.5",
                  "optimize_prompt_options": "Must be an object",
                  "image": "Passing it triggers single- or multi-image image-to-image or editing; `/v1/images/edits` requires at least 1. URLs are not downloaded or size-checked at submission",
                  "watermark": "Always `false` server-side",
                  "mask": "Not supported: `/v1/images/edits` with `mask` returns 400 (`null` too)"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Synchronous success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Synchronous success (with `Prefer: respond-async` it is 202 with `task_id`; see below)",
                  "properties": {
                    "created": {
                      "type": "integer",
                      "description": "Unix seconds"
                    },
                    "data": {
                      "type": "array",
                      "description": "One entry per image",
                      "items": {
                        "type": "object",
                        "description": "",
                        "properties": {
                          "b64_json": {
                            "type": "string",
                            "description": "GPT Image / Gemini: Base64 image data; save it after decoding according to `output_format`. Gemini may return JPEG, so check `mime_type`"
                          },
                          "url": {
                            "type": "string",
                            "description": "Seedream: signed direct link valid for 24 hours; once expired, the only option is to regenerate"
                          },
                          "mime_type": {
                            "type": "string",
                            "description": "Image MIME type"
                          },
                          "revised_prompt": {
                            "type": "string",
                            "description": "Prompt as rewritten by the model (some models)"
                          }
                        }
                      }
                    },
                    "usage": {
                      "type": "object",
                      "description": "May be returned",
                      "properties": {
                        "input_tokens": {
                          "type": "integer",
                          "description": "Input tokens"
                        },
                        "output_tokens": {
                          "type": "integer",
                          "description": "Output tokens"
                        },
                        "total_tokens": {
                          "type": "integer",
                          "description": "Total"
                        }
                      }
                    }
                  },
                  "required": [
                    "data"
                  ]
                },
                "examples": {
                  "edit": {
                    "summary": "Image-to-image",
                    "value": {
                      "created": 1790222400,
                      "data": [
                        {
                          "b64_json": "iVBORw0KGgoAAA..."
                        }
                      ],
                      "usage": {
                        "input_tokens": 1310,
                        "output_tokens": 1056,
                        "total_tokens": 2366
                      }
                    }
                  },
                  "mask": {
                    "summary": "Masked inpainting",
                    "value": {
                      "created": 1790222400,
                      "data": [
                        {
                          "b64_json": "iVBORw0KGgoAAA..."
                        }
                      ],
                      "usage": {
                        "input_tokens": 2140,
                        "output_tokens": 1760,
                        "total_tokens": 3900
                      }
                    }
                  },
                  "multi": {
                    "summary": "Multiple references",
                    "value": {
                      "created": 1790222400,
                      "data": [
                        {
                          "url": "https://example.com/generated-image.png"
                        }
                      ]
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "With `Prefer: respond-async`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "",
                  "properties": {
                    "task_id": {
                      "type": "string",
                      "description": "Task ID"
                    },
                    "status": {
                      "type": "string",
                      "description": "`pending`"
                    },
                    "status_url": {
                      "type": "string",
                      "description": "Polling URL: `GET /v1/images/tasks?task_id=…` (putting the task ID in the path is not supported)"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid parameters (rejected before generation, not billed)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or expired API key (`missing_api_key` / `invalid_api_key` / `api_key_expired`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Balance, or key / member / department quota, exhausted (`insufficient_quota`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "The model is not in this key's group (`model_not_found`), or the path does not belong to the group (`route_not_found`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "Request body over 60 MB (`request_too_large`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Account or key concurrency cap reached (`user_concurrency_limit` / `apikey_concurrency_limit`), with `Retry-After`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-hopbase-slug": "images-edits",
        "x-hopbase-summary": "Image-to-image / image editing: GPT Image (supports mask), Seedream, and Gemini in the \"Gemini (all models, incl. image)\" group.",
        "x-hopbase-docs": "https://hop-base.com/zh-cn/docs/api-reference/images-edits",
        "x-hopbase-scenarios": [
          {
            "id": "edit",
            "label": "Image-to-image",
            "request": {
              "body": {
                "model": "gpt-image-2",
                "prompt": "Turn the reference image into an oil painting in the style of Van Gogh's The Starry Night",
                "image": "https://example.com/input.png",
                "size": "1536x1024",
                "quality": "medium"
              }
            },
            "response": {
              "status": 200,
              "body": {
                "created": 1790222400,
                "data": [
                  {
                    "b64_json": "iVBORw0KGgoAAA..."
                  }
                ],
                "usage": {
                  "input_tokens": 1310,
                  "output_tokens": 1056,
                  "total_tokens": 2366
                }
              }
            }
          },
          {
            "id": "mask",
            "label": "Masked inpainting",
            "request": {
              "body": {
                "model": "gpt-image-2.5-flare",
                "prompt": "Replace the masked area with a vase, styled after the second image",
                "image": [
                  "https://example.com/scene.png",
                  "https://example.com/style.png"
                ],
                "mask": "https://example.com/mask.png",
                "size": "1024x1024",
                "quality": "high"
              }
            },
            "response": {
              "status": 200,
              "body": {
                "created": 1790222400,
                "data": [
                  {
                    "b64_json": "iVBORw0KGgoAAA..."
                  }
                ],
                "usage": {
                  "input_tokens": 2140,
                  "output_tokens": 1760,
                  "total_tokens": 3900
                }
              }
            }
          },
          {
            "id": "multi",
            "label": "Multiple references",
            "request": {
              "body": {
                "model": "seedream-4-5",
                "prompt": "Place the person from the first image into the scene of the second image, keeping the lighting consistent",
                "image": [
                  "https://example.com/person.png",
                  "https://example.com/scene.png"
                ]
              }
            },
            "response": {
              "status": 200,
              "body": {
                "created": 1790222400,
                "data": [
                  {
                    "url": "https://example.com/generated-image.png"
                  }
                ]
              }
            }
          }
        ],
        "x-hopbase-related": [
          {
            "label": "Image generation guide",
            "href": "/docs/media/images"
          },
          {
            "label": "Image request builder",
            "href": "/docs/build"
          },
          {
            "label": "Create image",
            "href": "/docs/api-reference/images-generations"
          }
        ],
        "x-hopbase-sources": [
          "public/spec/models/*.json#/$defs/edits",
          "content/docs/media/images.zh-cn.mdx#端点一览"
        ]
      }
    },
    "/v1/video/generate": {
      "post": {
        "operationId": "createVideoTask",
        "summary": "Submit video task",
        "description": "Seedance, MiniMax, Kling and Grok video share this single submission endpoint. HopBase routes each request to the matching family based on the request's `model` and the key's group. **Request bodies and status values differ by family**; select a family below to see its parameters. After submitting, poll with [Get video task](https://hop-base.com/zh-cn/docs/api-reference/video-task).\n\nAt submission, the check is \"available balance − estimated cost of in-progress tasks − estimated cost of this task\"; if that is insufficient, it returns 402 `insufficient_balance`. Failed tasks are never billed; tasks cannot be cancelled; a Seedance task unfinished after 24 hours is automatically marked failed (`The task did not finish within 24 hours and was terminated automatically`). **Do not resubmit after a successful submission**: every resubmission is another billed task.\n\nWan 3.0 / HappyHorse use the native video path `POST /api/v1/services/aigc/video-generation/video-synthesis` (no `/v1` prefix); see [Wan and HappyHorse](https://hop-base.com/zh-cn/docs/media/bailian). Gemini Omni returns synchronously; see [Gemini Omni video](https://hop-base.com/zh-cn/docs/media/gemini).",
        "tags": [
          "Video"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "description": "Request body by family",
                "oneOf": [
                  {
                    "type": "object",
                    "description": "",
                    "properties": {
                      "model": {
                        "type": "string",
                        "description": "Seedance model ID; China groups also accept overseas `dreamina-*` IDs as compatibility aliases (4K is still rejected)",
                        "enum": [
                          "doubao-seedance-2-0-260128-a",
                          "doubao-seedance-2-0-fast-260128-a",
                          "doubao-seedance-2-0-mini-260615-a",
                          "doubao-seedance-2-5-260628-a",
                          "dreamina-seedance-2-0-260128",
                          "dreamina-seedance-2-0-ep",
                          "dreamina-seedance-2-0-fast-260128",
                          "dreamina-seedance-2-0-fast-ep",
                          "dreamina-seedance-2-0-fast-hc",
                          "dreamina-seedance-2-0-hc",
                          "dreamina-seedance-2-0-mini-260615",
                          "dreamina-seedance-2-0-mini-ep",
                          "dreamina-seedance-2-0-mini-hc",
                          "dreamina-seedance-2-5-260628"
                        ]
                      },
                      "content": {
                        "type": "array",
                        "description": "Prompt and reference media. Put the prompt in a `text` element; sending only a top-level `prompt` is rejected (`missing content`)",
                        "items": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "type": {
                              "enum": [
                                "text",
                                "image_url",
                                "video_url",
                                "audio_url"
                              ],
                              "description": "Writing it as `image` / `input_image` returns 400"
                            },
                            "text": {
                              "type": "string",
                              "description": "Prompt when `type: text`; must not be empty"
                            },
                            "image_url": {
                              "type": "object",
                              "description": "Must be an object `{\"url\": …}`; images may be base64 Data URLs, and Seedance 2.0 also accepts a ready `asset://<asset ID>`",
                              "properties": {
                                "url": {
                                  "type": "string",
                                  "description": "HTTP(S) URL or Data URL"
                                }
                              },
                              "required": [
                                "url"
                              ]
                            },
                            "video_url": {
                              "type": "object",
                              "description": "Video does not accept Data URLs",
                              "properties": {
                                "url": {
                                  "type": "string",
                                  "description": "HTTP(S) URL or Data URL"
                                }
                              },
                              "required": [
                                "url"
                              ]
                            },
                            "audio_url": {
                              "type": "object",
                              "description": "Audio may be a Data URL",
                              "properties": {
                                "url": {
                                  "type": "string",
                                  "description": "HTTP(S) URL or Data URL"
                                }
                              },
                              "required": [
                                "url"
                              ]
                            },
                            "role": {
                              "type": "string",
                              "description": "Images: `first_frame` / `last_frame` / `reference_image`; if omitted, video defaults to `reference_video` and audio to `reference_audio`. A single image without a role is treated as the first frame; multiple images must set it; first/last frames cannot be mixed with reference media"
                            }
                          },
                          "required": [
                            "type"
                          ]
                        },
                        "minItems": 1,
                        "x-hopbase-limits": "Reference images: 2.0 ≤ 9, 2.5 ≤ 30; videos: 2.0 ≤ 3, 2.5 ≤ 10; audio: 2.0 ≤ 3 (must be paired with an image or video), 2.5 ≤ 10; at most 2 first/last frames"
                      },
                      "duration": {
                        "type": "integer",
                        "description": "2.0: 4–15 or `-1` (auto); 2.5: 4–30 or `-1`. Defaults: `5` on 2.0, `-1` on 2.5; with `-1` the balance is reserved for the longest duration",
                        "minimum": -1,
                        "maximum": 30
                      },
                      "resolution": {
                        "type": "string",
                        "description": "Available tiers vary by model (overseas 2.0 standard includes 4K; Fast / Mini only 480p / 720p; 2.5 does not support 4K)",
                        "enum": [
                          "480p",
                          "720p",
                          "1080p",
                          "4k"
                        ],
                        "default": "720p"
                      },
                      "ratio": {
                        "type": "string",
                        "description": "Aspect ratio",
                        "enum": [
                          "16:9",
                          "4:3",
                          "1:1",
                          "3:4",
                          "9:16",
                          "21:9",
                          "adaptive"
                        ],
                        "default": "adaptive"
                      },
                      "generate_audio": {
                        "type": "boolean",
                        "description": "Defaults to `true` on 2.5; not filled in on 2.0, so pass it explicitly"
                      },
                      "watermark": {
                        "type": "boolean",
                        "description": "Defaults to `false` on 2.5; not filled in on 2.0, so pass it explicitly"
                      },
                      "return_last_frame": {
                        "type": "boolean",
                        "description": "Returns `task.last_frame_url` when the last frame is available; defaults to `true` on 2.5, not guaranteed on 2.0"
                      },
                      "priority": {
                        "type": "integer",
                        "description": "Task priority",
                        "minimum": 0,
                        "maximum": 9
                      },
                      "execution_expires_after": {
                        "type": "integer",
                        "description": "Seconds; does not change the 24-hour fallback",
                        "minimum": 3600,
                        "maximum": 259200
                      },
                      "callback_url": {
                        "type": "string",
                        "description": "HTTP(S) URL; not a substitute for polling"
                      },
                      "safety_identifier": {
                        "type": "string",
                        "description": "1–64 ASCII characters",
                        "minLength": 1,
                        "maxLength": 64
                      }
                    },
                    "required": [
                      "model",
                      "content"
                    ],
                    "title": "Seedance",
                    "x-hopbase-doc": "/docs/media/seedance",
                    "x-hopbase-note": "Strict types: integers and booleans written as strings are rejected. `frames`, `seed`, `camera_fixed`, `draft`, `draft_task` and `service_tier` return 400; `size`, `seconds`, `n` and `aspect_ratio` are not Seedance parameters and are ignored without an error. Request body cap 64 MB."
                  },
                  {
                    "type": "object",
                    "description": "",
                    "properties": {
                      "model": {
                        "type": "string",
                        "description": "Exact ID, no aliases",
                        "enum": [
                          "MiniMax-H3",
                          "MiniMax-H3-Max"
                        ]
                      },
                      "content": {
                        "type": "array",
                        "description": "Exactly 1 `text` element plus optional media elements; first/last frames and `reference_*` are mutually exclusive within one request; at most 12 media items in total",
                        "items": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "type": {
                              "enum": [
                                "text",
                                "image_url",
                                "video_url",
                                "audio_url"
                              ]
                            },
                            "text": {
                              "type": "string",
                              "description": "Prompt, 1–7000 characters"
                            },
                            "image_url": {
                              "type": "object",
                              "description": "JPG / JPEG / PNG / WEBP / HEIC / HEIF, ≤ 30 MB each, sides 256–5760 px, aspect ratio between 5:2 and 2:5",
                              "properties": {
                                "url": {
                                  "type": "string",
                                  "description": "HTTP(S) URL or Data URL"
                                }
                              },
                              "required": [
                                "url"
                              ]
                            },
                            "video_url": {
                              "type": "object",
                              "description": "H3 only; H.264 / H.265, ≤ 50 MB and 2–15 seconds per clip, ≤ 15 seconds in total",
                              "properties": {
                                "url": {
                                  "type": "string",
                                  "description": "HTTP(S) URL or Data URL"
                                }
                              },
                              "required": [
                                "url"
                              ]
                            },
                            "audio_url": {
                              "type": "object",
                              "description": "H3 only; requires an image or video reference as well; WAV / MP3, ≤ 15 MB and 2–15 seconds per clip",
                              "properties": {
                                "url": {
                                  "type": "string",
                                  "description": "HTTP(S) URL or Data URL"
                                }
                              },
                              "required": [
                                "url"
                              ]
                            },
                            "role": {
                              "type": "string",
                              "description": "Images: `first_frame` / `last_frame` (≤ 1 each) or `reference_image` (H3 only, ≤ 9); video must use `reference_video` (≤ 3), audio must use `reference_audio` (≤ 3). An image without a role is treated as the first frame"
                            }
                          },
                          "required": [
                            "type"
                          ]
                        },
                        "minItems": 1
                      },
                      "resolution": {
                        "type": "string",
                        "description": "H3: `768P` / `2K`; H3-Max: `480P` / `768P`. Also determines the billing tier",
                        "enum": [
                          "480P",
                          "768P",
                          "2K"
                        ]
                      },
                      "duration": {
                        "type": "integer",
                        "description": "Whole seconds; H3: 4–15; H3-Max: 5–15. Auto duration is not supported",
                        "minimum": 4,
                        "maximum": 15
                      },
                      "ratio": {
                        "type": "string",
                        "description": "Required for text-to-video only, and cannot be `adaptive`; multimodal references default to `adaptive`; first/last-frame mode always outputs `adaptive`",
                        "enum": [
                          "21:9",
                          "16:9",
                          "4:3",
                          "1:1",
                          "3:4",
                          "9:16",
                          "adaptive"
                        ]
                      },
                      "aigc_watermark": {
                        "type": "boolean",
                        "description": "Adds an AI-generated content watermark to the output"
                      }
                    },
                    "required": [
                      "model",
                      "content",
                      "resolution",
                      "duration"
                    ],
                    "title": "MiniMax Hailuo",
                    "additionalProperties": false,
                    "x-hopbase-doc": "/docs/media/minimax",
                    "x-hopbase-note": "Strict decoding: only the fields below are accepted at the top level; any other field (including `prompt` / `size` / `n` / `seconds` / `image` and `callback_url`) returns 400. Submission returns 202 with an `mmt…` task ID. Request body cap 64 MiB."
                  },
                  {
                    "type": "object",
                    "description": "",
                    "properties": {
                      "model": {
                        "type": "string",
                        "description": "A video ID from the model matrix; image model IDs return 400",
                        "enum": [
                          "kling-avatar",
                          "kling-lip-sync",
                          "kling-o1",
                          "kling-v1-6",
                          "kling-v2-0",
                          "kling-v2-1",
                          "kling-v2-5-turbo",
                          "kling-v2-6",
                          "kling-v2-6-motion-control",
                          "kling-v3",
                          "kling-v3-motion-control",
                          "kling-v3-omni",
                          "kling-v3-turbo"
                        ]
                      },
                      "prompt": {
                        "type": "string",
                        "description": "Required when there is no media; may be empty only with `images` / `videos`; not needed for lip sync",
                        "maxLength": 2500
                      },
                      "duration": {
                        "type": "integer",
                        "description": "Ranges per model are in the [Kling model matrix](https://hop-base.com/zh-cn/docs/media/kling#model-matrix); `kling-v2-6` accepts only 5 / 10. Do not send it for motion control, avatar or lip sync; the duration comes from the media",
                        "default": 5
                      },
                      "resolution": {
                        "type": "string",
                        "description": "Case-insensitive; available tiers per model are on the Kling page",
                        "enum": [
                          "720p",
                          "1080p",
                          "2k",
                          "4k"
                        ],
                        "default": "720p"
                      },
                      "aspect_ratio": {
                        "type": "string",
                        "description": "The gateway does not fill it in when omitted",
                        "enum": [
                          "16:9",
                          "9:16",
                          "1:1"
                        ]
                      },
                      "audio": {
                        "type": "boolean",
                        "description": "Whether to generate sound; see the Kling page per model",
                        "default": false
                      },
                      "images": {
                        "type": "array",
                        "description": "First/last frames or reference images; required for motion control / avatar; counts per the model matrix",
                        "items": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "url": {
                              "type": "string",
                              "description": "Public HTTP(S) URL"
                            },
                            "file_id": {
                              "type": "string",
                              "description": "Kling asset ID; use either this or `url`"
                            },
                            "usage": {
                              "type": "string",
                              "description": "Required for ordinary generation: `first_frame` / `last_frame` / `reference`"
                            }
                          }
                        }
                      },
                      "videos": {
                        "type": "array",
                        "description": "Reference / edit video, ≤ 1 item; required for motion control",
                        "items": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "url": {
                              "type": "string",
                              "description": "Public HTTP(S) URL"
                            },
                            "file_id": {
                              "type": "string",
                              "description": "Kling asset ID; use either this or `url`"
                            },
                            "reference_type": {
                              "type": "string",
                              "description": "Required: `feature` / `base`"
                            },
                            "keep_original_sound": {
                              "type": "boolean",
                              "description": "Keep the original audio"
                            }
                          }
                        },
                        "maxItems": 1
                      },
                      "subjects": {
                        "type": "array",
                        "description": "Custom subjects, only on `kling-v3-turbo`, `kling-v3`, `kling-v3-omni`",
                        "items": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "id": {
                              "type": "string",
                              "description": "Subject ID (required)"
                            },
                            "name": {
                              "type": "string",
                              "description": "Name"
                            }
                          },
                          "required": [
                            "id"
                          ]
                        }
                      },
                      "shots": {
                        "type": "object",
                        "description": "Shots, ≤ 6 segments; only on `kling-v3`, `kling-v3-omni`",
                        "properties": {
                          "mode": {
                            "type": "string",
                            "description": "Shot mode"
                          },
                          "segments": {
                            "type": "array",
                            "description": "Shot segments"
                          }
                        }
                      },
                      "extra": {
                        "type": "object",
                        "description": "Required for avatar / lip sync; motion control may pass `character_orientation`; ordinary video models return 400 for any key"
                      }
                    },
                    "required": [
                      "model"
                    ],
                    "title": "Kling",
                    "additionalProperties": false,
                    "x-hopbase-doc": "/docs/media/kling",
                    "x-hopbase-note": "Strict JSON contract: only the fields below are accepted; `size`, `response_format`, `user`, `n`, top-level `image_url` / `video_url`, etc. return 400 and are not billed. `voice_ids` is currently unavailable. Submission returns 202 with a `kt…` task ID."
                  },
                  {
                    "type": "object",
                    "description": "",
                    "properties": {
                      "model": {
                        "const": "grok-imagine-video-1.5",
                        "description": "Exact match"
                      },
                      "prompt": {
                        "type": "string",
                        "description": "Use either this or `content`"
                      },
                      "content": {
                        "type": "array",
                        "description": "Use either this or `prompt`; contains only `text` elements, and the text must not be empty",
                        "items": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "type": {
                              "const": "text"
                            },
                            "text": {
                              "type": "string",
                              "description": "Prompt"
                            }
                          }
                        }
                      },
                      "resolution": {
                        "type": "string",
                        "description": "With `reference_images`, only `480p` / `720p`; billed per second at that tier",
                        "enum": [
                          "480p",
                          "720p",
                          "1080p"
                        ]
                      },
                      "duration": {
                        "type": "integer",
                        "description": "Billed by the output `duration_seconds`; server default 5",
                        "minimum": 1,
                        "maximum": 15
                      },
                      "aspect_ratio": {
                        "type": "string",
                        "description": "Server default `16:9`; passing `ratio` is rejected",
                        "enum": [
                          "1:1",
                          "16:9",
                          "9:16",
                          "4:3",
                          "3:4",
                          "3:2",
                          "2:3"
                        ]
                      },
                      "reference_images": {
                        "type": "array",
                        "description": "Publicly reachable HTTP(S) only; Data URLs / `asset://` are not accepted; each reference image is billed separately",
                        "items": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "url": {
                              "type": "string",
                              "description": "Public HTTP(S) URL"
                            }
                          },
                          "required": [
                            "url"
                          ]
                        }
                      },
                      "priority": {
                        "type": "integer",
                        "description": "Task priority",
                        "minimum": 0,
                        "maximum": 9
                      },
                      "execution_expires_after": {
                        "type": "integer",
                        "description": "Seconds; does not change the 24-hour stale-task fallback",
                        "minimum": 3600,
                        "maximum": 259200
                      },
                      "callback_url": {
                        "type": "string",
                        "description": "Valid HTTP(S) URL; not a substitute for polling"
                      },
                      "safety_identifier": {
                        "type": "string",
                        "description": "1–64 ASCII characters, passed through as-is",
                        "minLength": 1,
                        "maxLength": 64
                      }
                    },
                    "required": [
                      "model",
                      "resolution"
                    ],
                    "title": "Grok Imagine",
                    "x-hopbase-doc": "/docs/media/grok",
                    "x-hopbase-note": "`ratio`, `frames`, `seed`, `camera_fixed`, `draft`, `draft_task`, `service_tier`, `generate_audio`, `watermark` and `return_last_frame` are rejected. Submission returns 200 with `task.id` (`vt…`)."
                  }
                ]
              },
              "examples": {
                "seedance": {
                  "summary": "Seedance",
                  "value": {
                    "model": "dreamina-seedance-2-5-260628",
                    "content": [
                      {
                        "type": "text",
                        "text": "An orange cat running across a sunlit meadow, tracking shot"
                      }
                    ],
                    "duration": 5,
                    "resolution": "720p",
                    "ratio": "16:9",
                    "generate_audio": false,
                    "watermark": false
                  }
                },
                "minimax": {
                  "summary": "MiniMax",
                  "value": {
                    "model": "MiniMax-H3",
                    "content": [
                      {
                        "type": "text",
                        "text": "The camera slowly pushes forward as light and shadow gently flow across the scene"
                      },
                      {
                        "type": "image_url",
                        "image_url": {
                          "url": "https://example.com/first.jpg"
                        },
                        "role": "first_frame"
                      }
                    ],
                    "resolution": "768P",
                    "duration": 4
                  }
                },
                "kling": {
                  "summary": "Kling",
                  "value": {
                    "model": "kling-v3",
                    "prompt": "A red ball rolling across a white table",
                    "duration": 5,
                    "resolution": "720p"
                  }
                },
                "grok": {
                  "summary": "Grok",
                  "value": {
                    "model": "grok-imagine-video-1.5",
                    "prompt": "An orange cat running through a sunlit meadow, camera following",
                    "resolution": "720p",
                    "duration": 5,
                    "aspect_ratio": "16:9"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Seedance / Grok submitted",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Submitted (2xx only means accepted). Status codes and shapes differ per family: Seedance / Grok return 200 with a `task` wrapper; MiniMax / Kling return 202 with a top-level `id`",
                  "anyOf": [
                    {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "task": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "id": {
                              "type": "string",
                              "description": "HopBase task ID, `vt…`"
                            },
                            "model": {
                              "type": "string",
                              "description": "Model ID"
                            },
                            "status": {
                              "type": "string",
                              "description": "`pending` or `processing`"
                            },
                            "outputs": {
                              "type": "array",
                              "description": "Always empty; query for results",
                              "items": {
                                "type": "string"
                              }
                            },
                            "error": {
                              "type": [
                                "object",
                                "null"
                              ]
                            },
                            "created_at": {
                              "type": "string",
                              "description": "RFC 3339"
                            },
                            "completed_at": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          }
                        }
                      },
                      "title": "Seedance / Grok (200)"
                    },
                    {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "Task ID: MiniMax `mmt…`, Kling `kt…`"
                        },
                        "object": {
                          "type": "string",
                          "description": "`video.generation.task`"
                        },
                        "model": {
                          "type": "string",
                          "description": "Model ID"
                        },
                        "status": {
                          "type": "string",
                          "description": "`queued`"
                        },
                        "billing_bucket": {
                          "type": "string",
                          "description": "Billing tier (MiniMax)"
                        }
                      },
                      "title": "MiniMax / Kling (202)"
                    }
                  ]
                },
                "examples": {
                  "seedance": {
                    "summary": "Seedance",
                    "value": {
                      "task": {
                        "id": "vtEXAMPLE",
                        "model": "dreamina-seedance-2-5-260628",
                        "status": "pending",
                        "outputs": [],
                        "error": null,
                        "created_at": "2026-09-23T08:00:00Z",
                        "completed_at": null
                      }
                    }
                  },
                  "grok": {
                    "summary": "Grok",
                    "value": {
                      "task": {
                        "id": "vtEXAMPLE",
                        "model": "grok-imagine-video-1.5",
                        "status": "pending",
                        "outputs": [],
                        "error": null,
                        "created_at": "2026-09-23T08:00:00Z",
                        "completed_at": null
                      }
                    }
                  }
                }
              }
            }
          },
          "202": {
            "description": "MiniMax / Kling submitted",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Submitted (2xx only means accepted). Status codes and shapes differ per family: Seedance / Grok return 200 with a `task` wrapper; MiniMax / Kling return 202 with a top-level `id`",
                  "anyOf": [
                    {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "task": {
                          "type": "object",
                          "description": "",
                          "properties": {
                            "id": {
                              "type": "string",
                              "description": "HopBase task ID, `vt…`"
                            },
                            "model": {
                              "type": "string",
                              "description": "Model ID"
                            },
                            "status": {
                              "type": "string",
                              "description": "`pending` or `processing`"
                            },
                            "outputs": {
                              "type": "array",
                              "description": "Always empty; query for results",
                              "items": {
                                "type": "string"
                              }
                            },
                            "error": {
                              "type": [
                                "object",
                                "null"
                              ]
                            },
                            "created_at": {
                              "type": "string",
                              "description": "RFC 3339"
                            },
                            "completed_at": {
                              "type": [
                                "string",
                                "null"
                              ]
                            }
                          }
                        }
                      },
                      "title": "Seedance / Grok (200)"
                    },
                    {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "Task ID: MiniMax `mmt…`, Kling `kt…`"
                        },
                        "object": {
                          "type": "string",
                          "description": "`video.generation.task`"
                        },
                        "model": {
                          "type": "string",
                          "description": "Model ID"
                        },
                        "status": {
                          "type": "string",
                          "description": "`queued`"
                        },
                        "billing_bucket": {
                          "type": "string",
                          "description": "Billing tier (MiniMax)"
                        }
                      },
                      "title": "MiniMax / Kling (202)"
                    }
                  ]
                },
                "examples": {
                  "minimax": {
                    "summary": "MiniMax",
                    "value": {
                      "id": "mmt60x430684635582774",
                      "object": "video.generation.task",
                      "model": "MiniMax-H3",
                      "status": "queued",
                      "billing_bucket": "768p"
                    }
                  },
                  "kling": {
                    "summary": "Kling",
                    "value": {
                      "id": "kt57xEXAMPLE",
                      "object": "video.generation.task",
                      "model": "kling-v3",
                      "status": "queued"
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Parameter validation failed; returned synchronously, no task is created, not billed. Most have only `error.message`, no `code`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "`insufficient_balance`: the balance does not cover in-flight reservations plus this estimate; when a member quota is short, `message` starts with `Insufficient quota:`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "The model is not in this key's group: `The current group does not support the requested model: <model ID>`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "Request body over the limit",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Reference media were not downloaded and parsed within 2 minutes (`upstream_timeout`, `media validation timed out, please retry later`); retry the same request later",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-hopbase-slug": "video-generate",
        "x-hopbase-summary": "Unified submission endpoint for async video generation: shared by Seedance, MiniMax Hailuo, Kling and Grok Imagine, dispatched by model and key group.",
        "x-hopbase-docs": "https://hop-base.com/zh-cn/docs/api-reference/video-generate",
        "x-hopbase-scenarios": [
          {
            "id": "seedance",
            "label": "Seedance",
            "request": {
              "body": {
                "model": "dreamina-seedance-2-5-260628",
                "content": [
                  {
                    "type": "text",
                    "text": "An orange cat running across a sunlit meadow, tracking shot"
                  }
                ],
                "duration": 5,
                "resolution": "720p",
                "ratio": "16:9",
                "generate_audio": false,
                "watermark": false
              }
            },
            "response": {
              "status": 200,
              "body": {
                "task": {
                  "id": "vtEXAMPLE",
                  "model": "dreamina-seedance-2-5-260628",
                  "status": "pending",
                  "outputs": [],
                  "error": null,
                  "created_at": "2026-09-23T08:00:00Z",
                  "completed_at": null
                }
              }
            }
          },
          {
            "id": "minimax",
            "label": "MiniMax",
            "request": {
              "body": {
                "model": "MiniMax-H3",
                "content": [
                  {
                    "type": "text",
                    "text": "The camera slowly pushes forward as light and shadow gently flow across the scene"
                  },
                  {
                    "type": "image_url",
                    "image_url": {
                      "url": "https://example.com/first.jpg"
                    },
                    "role": "first_frame"
                  }
                ],
                "resolution": "768P",
                "duration": 4
              }
            },
            "response": {
              "status": 202,
              "body": {
                "id": "mmt60x430684635582774",
                "object": "video.generation.task",
                "model": "MiniMax-H3",
                "status": "queued",
                "billing_bucket": "768p"
              }
            }
          },
          {
            "id": "kling",
            "label": "Kling",
            "request": {
              "body": {
                "model": "kling-v3",
                "prompt": "A red ball rolling across a white table",
                "duration": 5,
                "resolution": "720p"
              }
            },
            "response": {
              "status": 202,
              "body": {
                "id": "kt57xEXAMPLE",
                "object": "video.generation.task",
                "model": "kling-v3",
                "status": "queued"
              }
            }
          },
          {
            "id": "grok",
            "label": "Grok",
            "request": {
              "body": {
                "model": "grok-imagine-video-1.5",
                "prompt": "An orange cat running through a sunlit meadow, camera following",
                "resolution": "720p",
                "duration": 5,
                "aspect_ratio": "16:9"
              }
            },
            "response": {
              "status": 200,
              "body": {
                "task": {
                  "id": "vtEXAMPLE",
                  "model": "grok-imagine-video-1.5",
                  "status": "pending",
                  "outputs": [],
                  "error": null,
                  "created_at": "2026-09-23T08:00:00Z",
                  "completed_at": null
                }
              }
            }
          }
        ],
        "x-hopbase-related": [
          {
            "label": "Video generation overview",
            "href": "/docs/media/video"
          },
          {
            "label": "Get video task",
            "href": "/docs/api-reference/video-task"
          },
          {
            "label": "Async task failures",
            "href": "/docs/reference/errors#async-task-failures"
          }
        ],
        "x-hopbase-sources": [
          "content/docs/media/video.zh-cn.mdx",
          "content/docs/media/minimax.zh-cn.mdx#请求契约",
          "content/docs/media/kling.zh-cn.mdx#接口",
          "content/docs/media/grok.zh-cn.mdx#视频"
        ]
      }
    },
    "/v1/video/tasks/{task_id}": {
      "get": {
        "operationId": "getVideoTask",
        "summary": "Get video task",
        "description": "Poll with the task ID returned at submission, ideally every 5 seconds; polling uses no concurrency and is not billed. Seedance / Grok responses are wrapped in `task`, while MiniMax / Kling use top-level fields; do not read the wrong level.\n\nA Seedance task still unfinished 24 hours after creation is automatically marked failed (not billed), with `task.error.message` set to `The task did not finish within 24 hours and was terminated automatically`. Result URLs are signed URLs under `api.hop-base.com`; querying again returns the same URL and **does not renew it**: 30 days for Seedance and Grok, 6 hours for Kling and MiniMax. Download and save them before they expire. Unfinished tasks are marked failed after 24 hours (Seedance) or 2 hours (Kling, MiniMax).",
        "tags": [
          "Video"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "task_id",
            "in": "path",
            "required": true,
            "description": "Task ID returned at submission: `vt…` (Seedance / Grok), `mmt…` (MiniMax), `kt…` (Kling)",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Task object (including failed tasks)",
            "content": {
              "application/json": {
                "schema": {
                  "description": "Task object. Queries always return 200; when generation fails, `status` is `failed` and the reason is in `error.message` (English, no `code`; Kling is the exception)",
                  "anyOf": [
                    {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "task": {
                          "type": "object",
                          "description": "Task",
                          "properties": {
                            "id": {
                              "type": "string",
                              "description": "`vt…`"
                            },
                            "model": {
                              "type": "string",
                              "description": "Model ID"
                            },
                            "status": {
                              "enum": [
                                "pending",
                                "processing",
                                "completed",
                                "failed"
                              ],
                              "description": "Only these four values; read `outputs` only when `completed`"
                            },
                            "duration_seconds": {
                              "type": "integer",
                              "description": "Output duration in seconds; for auto-duration tasks, read it after completion"
                            },
                            "outputs": {
                              "type": "array",
                              "description": "Output URLs (array of strings, not `{url}` objects); signed `api.hop-base.com` URLs valid for 30 days from completion, not renewed; expired URLs return 410",
                              "items": {
                                "type": "string"
                              }
                            },
                            "last_frame_url": {
                              "type": "string",
                              "description": "Optional, present only when the last frame is available; re-signed on every query"
                            },
                            "usage": {
                              "type": "object",
                              "description": "Optional; tokens, not a monetary amount",
                              "properties": {
                                "completion_tokens": {
                                  "type": "integer",
                                  "description": "Tokens billed for this task"
                                },
                                "total_tokens": {
                                  "type": "integer",
                                  "description": "Total"
                                }
                              }
                            },
                            "error": {
                              "type": [
                                "object",
                                "null"
                              ],
                              "description": "On failure `{\"message\": \"<English failure reason>\"}`; links are replaced with `[URL_REDACTED]`"
                            },
                            "created_at": {
                              "type": "string",
                              "description": "RFC 3339"
                            },
                            "completed_at": {
                              "type": [
                                "string",
                                "null"
                              ],
                              "description": "`null` while unfinished"
                            }
                          }
                        },
                        "usage": {
                          "type": "object",
                          "description": "Present only after the task ends, and returned only to the key that created the task. `0` means it failed and was not charged",
                          "properties": {
                            "cost": {
                              "type": "number",
                              "description": "Amount actually deducted from the balance for this task (ledger currency)"
                            },
                            "currency": {
                              "type": "string",
                              "description": "Ledger currency, currently `CNY`"
                            },
                            "cost_cny": {
                              "type": "number",
                              "description": "Amount in CNY"
                            },
                            "cost_usd": {
                              "type": "number",
                              "description": "Amount in USD (fixed 1 USD = 6.8 CNY)"
                            }
                          }
                        }
                      },
                      "title": "Seedance / Grok"
                    },
                    {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "`mmt…` / `kt…`"
                        },
                        "status": {
                          "type": "string",
                          "description": "`queued` → `processing` → `completed` | `failed`; only the last two are terminal, treat any other value as in progress"
                        },
                        "outputs": {
                          "type": "array",
                          "description": "Output URL; valid for 6 hours from completion, not renewed; expired URLs return 410",
                          "items": {
                            "type": "string"
                          }
                        },
                        "error": {
                          "type": "object",
                          "description": "Failure reason; Kling includes a stable `error.code` (such as `input_sensitive`, `generation_failed`)",
                          "properties": {
                            "message": {
                              "type": "string",
                              "description": "English description"
                            },
                            "code": {
                              "type": "string",
                              "description": "Kling only"
                            }
                          }
                        },
                        "usage": {
                          "type": "object",
                          "description": "Billing details + amount charged",
                          "properties": {
                            "bucket": {
                              "type": "string",
                              "description": "MiniMax billing tier"
                            },
                            "billed_seconds": {
                              "type": "integer",
                              "description": "MiniMax billed seconds"
                            },
                            "input_seconds": {
                              "type": "integer",
                              "description": "MiniMax reference video input seconds"
                            },
                            "extra_input_images": {
                              "type": "integer",
                              "description": "MiniMax reference images beyond the free allowance"
                            },
                            "cost": {
                              "type": "number",
                              "description": "Amount actually deducted for this task"
                            },
                            "currency": {
                              "type": "string",
                              "description": "Ledger currency"
                            }
                          }
                        }
                      },
                      "title": "MiniMax / Kling"
                    }
                  ]
                },
                "examples": {
                  "seedance-done": {
                    "summary": "Seedance completed",
                    "value": {
                      "task": {
                        "id": "vtEXAMPLE",
                        "model": "dreamina-seedance-2-5-260628",
                        "status": "completed",
                        "duration_seconds": 5,
                        "outputs": [
                          "https://api.hop-base.com/example-signed-video.mp4"
                        ],
                        "last_frame_url": "https://api.hop-base.com/example-signed-last-frame.jpg",
                        "usage": {
                          "completion_tokens": 1000,
                          "total_tokens": 1000
                        },
                        "error": null,
                        "created_at": "2026-09-23T08:00:00Z",
                        "completed_at": "2026-09-23T08:03:10Z"
                      },
                      "usage": {
                        "cost": 3.4,
                        "currency": "CNY",
                        "cost_cny": 3.4,
                        "cost_usd": 0.5
                      }
                    }
                  },
                  "seedance-failed": {
                    "summary": "Failed",
                    "value": {
                      "task": {
                        "id": "vtEXAMPLE",
                        "status": "failed",
                        "outputs": [],
                        "error": {
                          "message": "<English failure reason>"
                        }
                      },
                      "usage": {
                        "cost": 0,
                        "currency": "CNY",
                        "cost_cny": 0,
                        "cost_usd": 0
                      }
                    }
                  },
                  "seedance-timeout": {
                    "summary": "24-hour timeout",
                    "value": {
                      "task": {
                        "id": "vtEXAMPLE",
                        "status": "failed",
                        "outputs": [],
                        "error": {
                          "message": "The task did not finish within 24 hours and was terminated automatically"
                        }
                      },
                      "usage": {
                        "cost": 0,
                        "currency": "CNY",
                        "cost_cny": 0,
                        "cost_usd": 0
                      }
                    }
                  },
                  "minimax-done": {
                    "summary": "MiniMax completed",
                    "value": {
                      "id": "mmt60x430684635582774",
                      "status": "completed",
                      "outputs": [
                        "https://api.hop-base.com/..."
                      ],
                      "usage": {
                        "bucket": "2k",
                        "billed_seconds": 4,
                        "input_seconds": 0,
                        "extra_input_images": 0,
                        "cost": 3.4,
                        "currency": "CNY"
                      }
                    }
                  },
                  "kling-running": {
                    "summary": "Kling in progress",
                    "value": {
                      "id": "kt57xEXAMPLE",
                      "status": "processing",
                      "outputs": []
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or expired API key (`missing_api_key` / `invalid_api_key` / `api_key_expired`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "The task does not exist or does not belong to this key",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-hopbase-slug": "video-task",
        "x-hopbase-summary": "Poll the status and result URLs of a single video task (and Kling and Midjourney image tasks).",
        "x-hopbase-docs": "https://hop-base.com/zh-cn/docs/api-reference/video-task",
        "x-hopbase-scenarios": [
          {
            "id": "seedance-done",
            "label": "Seedance completed",
            "request": {
              "path": {
                "task_id": "vtEXAMPLE"
              }
            },
            "response": {
              "status": 200,
              "body": {
                "task": {
                  "id": "vtEXAMPLE",
                  "model": "dreamina-seedance-2-5-260628",
                  "status": "completed",
                  "duration_seconds": 5,
                  "outputs": [
                    "https://api.hop-base.com/example-signed-video.mp4"
                  ],
                  "last_frame_url": "https://api.hop-base.com/example-signed-last-frame.jpg",
                  "usage": {
                    "completion_tokens": 1000,
                    "total_tokens": 1000
                  },
                  "error": null,
                  "created_at": "2026-09-23T08:00:00Z",
                  "completed_at": "2026-09-23T08:03:10Z"
                },
                "usage": {
                  "cost": 3.4,
                  "currency": "CNY",
                  "cost_cny": 3.4,
                  "cost_usd": 0.5
                }
              }
            }
          },
          {
            "id": "seedance-failed",
            "label": "Failed",
            "request": {
              "path": {
                "task_id": "vtEXAMPLE"
              }
            },
            "response": {
              "status": 200,
              "body": {
                "task": {
                  "id": "vtEXAMPLE",
                  "status": "failed",
                  "outputs": [],
                  "error": {
                    "message": "<English failure reason>"
                  }
                },
                "usage": {
                  "cost": 0,
                  "currency": "CNY",
                  "cost_cny": 0,
                  "cost_usd": 0
                }
              }
            }
          },
          {
            "id": "seedance-timeout",
            "label": "24-hour timeout",
            "request": {
              "path": {
                "task_id": "vtEXAMPLE"
              }
            },
            "response": {
              "status": 200,
              "body": {
                "task": {
                  "id": "vtEXAMPLE",
                  "status": "failed",
                  "outputs": [],
                  "error": {
                    "message": "The task did not finish within 24 hours and was terminated automatically"
                  }
                },
                "usage": {
                  "cost": 0,
                  "currency": "CNY",
                  "cost_cny": 0,
                  "cost_usd": 0
                }
              }
            }
          },
          {
            "id": "minimax-done",
            "label": "MiniMax completed",
            "request": {
              "path": {
                "task_id": "mmt60x430684635582774"
              }
            },
            "response": {
              "status": 200,
              "body": {
                "id": "mmt60x430684635582774",
                "status": "completed",
                "outputs": [
                  "https://api.hop-base.com/..."
                ],
                "usage": {
                  "bucket": "2k",
                  "billed_seconds": 4,
                  "input_seconds": 0,
                  "extra_input_images": 0,
                  "cost": 3.4,
                  "currency": "CNY"
                }
              }
            }
          },
          {
            "id": "kling-running",
            "label": "Kling in progress",
            "request": {
              "path": {
                "task_id": "kt57xEXAMPLE"
              }
            },
            "response": {
              "status": 200,
              "body": {
                "id": "kt57xEXAMPLE",
                "status": "processing",
                "outputs": []
              }
            }
          }
        ],
        "x-hopbase-related": [
          {
            "label": "Submit video task",
            "href": "/docs/api-reference/video-generate"
          },
          {
            "label": "List video tasks",
            "href": "/docs/api-reference/video-tasks-list"
          },
          {
            "label": "Async task failures",
            "href": "/docs/reference/errors#async-task-failures"
          }
        ],
        "x-hopbase-sources": [
          "content/docs/media/video.zh-cn.mdx#2-轮询任务状态",
          "content/docs/media/minimax.zh-cn.mdx#任务生命周期",
          "content/docs/media/kling.zh-cn.mdx#提交与轮询",
          "content/docs/reference/account-api.zh-cn.mdx#charges"
        ]
      }
    },
    "/v1/video/tasks": {
      "get": {
        "operationId": "listVideoTasks",
        "summary": "List video tasks",
        "description": "Lists tasks submitted through the API, paginated (tasks submitted from the console Studio are excluded). Each element is a task object with the same shape as [Get video task](https://hop-base.com/zh-cn/docs/api-reference/video-task). Wan / HappyHorse have no list endpoint.",
        "tags": [
          "Video"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "required": false,
            "description": "Page number, starting from 1",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Items per page",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Task list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "",
                  "properties": {
                    "tasks": {
                      "type": "array",
                      "description": "Task object",
                      "items": {
                        "type": "object"
                      }
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of tasks"
                    },
                    "totalPages": {
                      "type": "integer",
                      "description": "Total number of pages"
                    }
                  }
                },
                "examples": {
                  "list": {
                    "summary": "First page",
                    "value": {
                      "tasks": [
                        {
                          "id": "vtEXAMPLE",
                          "model": "dreamina-seedance-2-5-260628",
                          "status": "completed",
                          "outputs": [
                            "https://api.hop-base.com/example-signed-video.mp4"
                          ],
                          "created_at": "2026-09-23T08:00:00Z",
                          "completed_at": "2026-09-23T08:03:10Z"
                        }
                      ],
                      "total": 1,
                      "totalPages": 1
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or expired API key (`missing_api_key` / `invalid_api_key` / `api_key_expired`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-hopbase-slug": "video-tasks-list",
        "x-hopbase-summary": "Lists video tasks the current user submitted through the API, paginated.",
        "x-hopbase-docs": "https://hop-base.com/zh-cn/docs/api-reference/video-tasks-list",
        "x-hopbase-scenarios": [
          {
            "id": "list",
            "label": "First page",
            "request": {
              "query": {
                "page": 1,
                "limit": 20
              }
            },
            "response": {
              "status": 200,
              "body": {
                "tasks": [
                  {
                    "id": "vtEXAMPLE",
                    "model": "dreamina-seedance-2-5-260628",
                    "status": "completed",
                    "outputs": [
                      "https://api.hop-base.com/example-signed-video.mp4"
                    ],
                    "created_at": "2026-09-23T08:00:00Z",
                    "completed_at": "2026-09-23T08:03:10Z"
                  }
                ],
                "total": 1,
                "totalPages": 1
              }
            }
          }
        ],
        "x-hopbase-related": [
          {
            "label": "Get video task",
            "href": "/docs/api-reference/video-task"
          }
        ],
        "x-hopbase-sources": [
          "content/docs/media/video.zh-cn.mdx#2-轮询任务状态"
        ]
      }
    },
    "/v1/audio/speech": {
      "post": {
        "operationId": "createSpeech",
        "summary": "Create speech",
        "description": "Synthesizes text into audio synchronously; the response is the audio itself, with no task to poll. Works directly with the OpenAI SDK's `audio.speech.create`; only the Base URL and `model` / `voice` change. The two speech models belong to the separate **MiniMax Speech Official** group; keys from chat or video groups cannot call them.\n\nAny other field returns 400 `unknown field`, including `stream_format`, `sample_rate`, `language_boost` and `voice_setting`. For those, streaming output or cloned voices, use the native endpoint `POST /v1/t2a_v2`; see the [Text-to-speech guide](https://hop-base.com/zh-cn/docs/audio/speech). Billed per character: one Han character counts as 2 characters.",
        "tags": [
          "Speech"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "",
                "properties": {
                  "model": {
                    "type": "string",
                    "description": "Case-sensitive, no aliases; `tts-1` / `tts-1-hd` are not recognized",
                    "enum": [
                      "speech-2.8-hd",
                      "speech-2.8-turbo"
                    ]
                  },
                  "input": {
                    "type": "string",
                    "description": "Text to synthesize (the native endpoint `/v1/t2a_v2` allows up to 10000 characters)",
                    "minLength": 1,
                    "maxLength": 4096
                  },
                  "voice": {
                    "type": "string",
                    "description": "A system voice ID, a cloned voice ID, or an OpenAI voice name: `alloy`, `ash`, `ballad`, `cedar`, `coral`, `echo`, `fable`, `marin`, `nova`, `onyx`, `sage`, `shimmer`, `verse` (OpenAI voice names map to the default voice). Default: `Chinese (Mandarin)_News_Anchor` if the text contains Han characters, otherwise `English_expressive_narrator`"
                  },
                  "response_format": {
                    "type": "string",
                    "description": "`aac` returns 400; `opus` is 24 kHz in an Ogg container",
                    "enum": [
                      "mp3",
                      "opus",
                      "flac",
                      "wav",
                      "pcm"
                    ],
                    "default": "mp3"
                  },
                  "speed": {
                    "type": "number",
                    "description": "Out-of-range values return 400; in-range values are clamped to 0.5–2",
                    "minimum": 0.25,
                    "maximum": 4,
                    "default": 1
                  },
                  "instructions": {
                    "type": "string",
                    "description": "Accepted but ignored"
                  }
                },
                "required": [
                  "model",
                  "input"
                ],
                "additionalProperties": false
              },
              "examples": {
                "zh": {
                  "summary": "Chinese MP3",
                  "value": {
                    "model": "speech-2.8-turbo",
                    "input": "Hello, world.",
                    "voice": "Chinese (Mandarin)_News_Anchor",
                    "response_format": "mp3"
                  }
                },
                "openai-voice": {
                  "summary": "OpenAI voice name",
                  "value": {
                    "model": "speech-2.8-hd",
                    "input": "Hello, world.",
                    "voice": "alloy",
                    "response_format": "wav",
                    "speed": 1.2
                  }
                },
                "error": {
                  "summary": "Unknown field",
                  "value": {
                    "model": "speech-2.8-hd",
                    "input": "Hello",
                    "voice_setting": {
                      "voice_id": "Chinese (Mandarin)_News_Anchor"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Audio bytes. `Content-Type` follows `response_format`: `audio/mpeg`, `audio/ogg`, `audio/flac`, `audio/wav`, `audio/pcm`",
            "content": {
              "audio/mpeg": {
                "schema": {
                  "type": "string",
                  "format": "binary",
                  "description": "Audio bytes"
                }
              }
            }
          },
          "400": {
            "description": "`unknown field`, `input` too long, `speed` out of range, unsupported `response_format`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                },
                "examples": {
                  "error": {
                    "summary": "Unknown field",
                    "value": {
                      "error": {
                        "message": "unknown field \"voice_setting\"",
                        "type": "invalid_request_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or expired API key (`missing_api_key` / `invalid_api_key` / `api_key_expired`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Balance, or key / member / department quota, exhausted (`insufficient_quota`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "The model is not in this key's group (`model_not_found`), or the path does not belong to the group (`route_not_found`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "Request body over 60 MB (`request_too_large`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Account or key concurrency cap reached (`user_concurrency_limit` / `apikey_concurrency_limit`), with `Retry-After`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-hopbase-slug": "audio-speech",
        "x-hopbase-summary": "OpenAI-compatible text-to-speech (MiniMax Speech 2.8 HD / Turbo); the response is the audio bytes directly.",
        "x-hopbase-docs": "https://hop-base.com/zh-cn/docs/api-reference/audio-speech",
        "x-hopbase-scenarios": [
          {
            "id": "zh",
            "label": "Chinese MP3",
            "request": {
              "saveAs": "hello.mp3",
              "body": {
                "model": "speech-2.8-turbo",
                "input": "Hello, world.",
                "voice": "Chinese (Mandarin)_News_Anchor",
                "response_format": "mp3"
              }
            },
            "response": {
              "status": 200,
              "contentType": "audio/mpeg",
              "text": "HTTP/1.1 200 OK\nContent-Type: audio/mpeg\nx-request-id: EXAMPLE\n\n<audio bytes, written to hello.mp3>"
            }
          },
          {
            "id": "openai-voice",
            "label": "OpenAI voice name",
            "request": {
              "saveAs": "hello.wav",
              "body": {
                "model": "speech-2.8-hd",
                "input": "Hello, world.",
                "voice": "alloy",
                "response_format": "wav",
                "speed": 1.2
              }
            },
            "response": {
              "status": 200,
              "contentType": "audio/wav",
              "text": "HTTP/1.1 200 OK\nContent-Type: audio/wav\nx-request-id: EXAMPLE\n\n<audio bytes, written to hello.wav>"
            }
          },
          {
            "id": "error",
            "label": "Unknown field",
            "request": {
              "body": {
                "model": "speech-2.8-hd",
                "input": "Hello",
                "voice_setting": {
                  "voice_id": "Chinese (Mandarin)_News_Anchor"
                }
              }
            },
            "response": {
              "status": 400,
              "body": {
                "error": {
                  "message": "unknown field \"voice_setting\"",
                  "type": "invalid_request_error"
                }
              }
            }
          }
        ],
        "x-hopbase-related": [
          {
            "label": "Text-to-speech guide (native endpoint, voices, cloning)",
            "href": "/docs/audio/speech"
          },
          {
            "label": "Concurrency, timeouts, and billing",
            "href": "/docs/reference/limits"
          }
        ],
        "x-hopbase-sources": [
          "content/docs/audio/speech.zh-cn.mdx#openai-兼容入口",
          "content/docs/reference/limits.zh-cn.mdx#请求体大小"
        ]
      }
    },
    "/v1/models": {
      "get": {
        "operationId": "listModels",
        "summary": "List models",
        "description": "The list contains only models in the key's group and is returned in full in one response (no pagination). Keys from OpenAI-compatible groups get the OpenAI format; keys from Claude groups get the Anthropic format. **`data[].id` is the only field you should rely on**; other fields may be missing for some models, and unknown fields should be treated as optional.\n\nFor the public catalog and list prices without an API key, see `GET /api/v1/models/pricing`; fields are described in the [Account and catalog API](https://hop-base.com/zh-cn/docs/reference/account-api#public-model-catalog).",
        "tags": [
          "Account and catalog"
        ],
        "security": [
          {
            "bearer": []
          },
          {
            "apiKey": []
          }
        ],
        "responses": {
          "200": {
            "description": "Model list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "",
                  "properties": {
                    "object": {
                      "const": "list"
                    },
                    "data": {
                      "type": "array",
                      "description": "Model",
                      "items": {
                        "type": "object",
                        "description": "",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "The model ID to pass in requests, and the only field you should rely on"
                          },
                          "object": {
                            "const": "model"
                          },
                          "capabilities": {
                            "type": "array",
                            "description": "For example `chat`, `reasoning`, `image_generation`",
                            "items": {
                              "type": "string"
                            }
                          },
                          "image_only": {
                            "type": "boolean",
                            "description": "`true` for image models; not returned for other models"
                          },
                          "context_window": {
                            "type": "integer",
                            "description": "Tokens; the same value as `context_length` and `max_input_tokens`, written three ways; not returned when unpublished"
                          },
                          "max_output_tokens": {
                            "type": "integer",
                            "description": "Tokens; not returned when unpublished"
                          },
                          "created": {
                            "type": "integer",
                            "description": "Unix seconds: the time of this response, not the release date"
                          },
                          "owned_by": {
                            "type": "string",
                            "description": "`hopbase`"
                          },
                          "display_name": {
                            "type": "string",
                            "description": "Claude groups only"
                          },
                          "created_at": {
                            "type": "string",
                            "description": "Claude groups only: model release date (RFC 3339)"
                          }
                        }
                      }
                    },
                    "has_more": {
                      "type": "boolean",
                      "description": "Claude groups only, kept only for SDK compatibility: the list is never paginated"
                    },
                    "first_id": {
                      "type": "string",
                      "description": "Claude groups only"
                    },
                    "last_id": {
                      "type": "string",
                      "description": "Claude groups only"
                    }
                  }
                },
                "examples": {
                  "openai": {
                    "summary": "OpenAI group",
                    "value": {
                      "object": "list",
                      "data": [
                        {
                          "id": "gpt-6-astra",
                          "object": "model",
                          "created": 1790222400,
                          "owned_by": "hopbase",
                          "capabilities": [
                            "chat",
                            "reasoning"
                          ],
                          "context_window": 1050000,
                          "context_length": 1050000,
                          "max_input_tokens": 1050000,
                          "max_output_tokens": 128000
                        }
                      ]
                    }
                  },
                  "claude": {
                    "summary": "Claude group",
                    "value": {
                      "object": "list",
                      "data": [
                        {
                          "id": "claude-opus-5-5",
                          "object": "model",
                          "type": "model",
                          "display_name": "Claude Opus 5.5",
                          "created_at": "2026-09-22T00:00:00Z"
                        }
                      ],
                      "has_more": false,
                      "first_id": "claude-opus-5-5",
                      "last_id": "claude-haiku-4-5-20251001"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or expired API key (`missing_api_key` / `invalid_api_key` / `api_key_expired`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-hopbase-slug": "models",
        "x-hopbase-summary": "Lists the model IDs callable from this key's group; not billed and does not consume concurrency.",
        "x-hopbase-docs": "https://hop-base.com/zh-cn/docs/api-reference/models",
        "x-hopbase-scenarios": [
          {
            "id": "openai",
            "label": "OpenAI group",
            "request": {},
            "response": {
              "status": 200,
              "body": {
                "object": "list",
                "data": [
                  {
                    "id": "gpt-6-astra",
                    "object": "model",
                    "created": 1790222400,
                    "owned_by": "hopbase",
                    "capabilities": [
                      "chat",
                      "reasoning"
                    ],
                    "context_window": 1050000,
                    "context_length": 1050000,
                    "max_input_tokens": 1050000,
                    "max_output_tokens": 128000
                  }
                ]
              }
            }
          },
          {
            "id": "claude",
            "label": "Claude group",
            "request": {},
            "response": {
              "status": 200,
              "body": {
                "object": "list",
                "data": [
                  {
                    "id": "claude-opus-5-5",
                    "object": "model",
                    "type": "model",
                    "display_name": "Claude Opus 5.5",
                    "created_at": "2026-09-22T00:00:00Z"
                  }
                ],
                "has_more": false,
                "first_id": "claude-opus-5-5",
                "last_id": "claude-haiku-4-5-20251001"
              }
            }
          }
        ],
        "x-hopbase-related": [
          {
            "label": "Account and catalog API",
            "href": "/docs/reference/account-api#list-models"
          },
          {
            "label": "Models overview",
            "href": "/docs/models"
          }
        ],
        "x-hopbase-sources": [
          "content/docs/reference/account-api.zh-cn.mdx#list-models"
        ]
      }
    },
    "/v1/usage": {
      "get": {
        "operationId": "getUsage",
        "summary": "Get balance and quota",
        "description": "`balance` is what this key can spend right now: without a key quota it is the account balance; with a key quota it is the key's remaining quota. Keys of team members and departments are further capped by the remaining quota for the current period. A key with a quota still draws from the account balance, so once the account balance runs out, requests return 402 even if `balance` still shows credit.\n\n**Amounts are currently recorded in CNY, yet `unit` says `\"USD\"`**: `balance`, `remaining` and the unsuffixed `quota.*` values are all CNY. For reconciliation, read the `_cny` / `_usd` fields directly (`_usd` = `_cny` ÷ 6.8, fixed). This endpoint accepts only `Authorization: Bearer` and does not use the standard error shape: check `is_active` rather than relying only on the HTTP status.\n\nAsync task queries include the per-task charge `cost` / `cost_cny` / `cost_usd` in the root `usage` object once the task has ended; see [Charges](https://hop-base.com/zh-cn/docs/reference/account-api#charges).",
        "tags": [
          "Account and catalog"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Balance and quota; also 200 when the key has expired or the member is disabled, with `is_active: false`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "",
                  "properties": {
                    "is_active": {
                      "type": "boolean",
                      "description": "`true` when `balance` is greater than 0"
                    },
                    "balance": {
                      "type": "number",
                      "description": "What this key can spend right now (ledger currency)"
                    },
                    "remaining": {
                      "type": "number",
                      "description": "Same as `balance`"
                    },
                    "unit": {
                      "type": "string",
                      "description": "Always `\"USD\"`; does not indicate the currency"
                    },
                    "ledger_currency": {
                      "type": "string",
                      "description": "Actual currency of unsuffixed amounts, currently `\"CNY\"`"
                    },
                    "exchange_rate": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "cny_per_usd": {
                          "type": "number",
                          "description": "`6.8`, a fixed conversion"
                        },
                        "basis": {
                          "type": "string",
                          "description": "`\"fixed unit rate\"`: not a live exchange rate"
                        }
                      }
                    },
                    "balance_cny": {
                      "type": "number",
                      "description": "`balance` in CNY"
                    },
                    "balance_usd": {
                      "type": "number",
                      "description": "`balance` in USD"
                    },
                    "quota": {
                      "type": "object",
                      "description": "Key quota",
                      "properties": {
                        "remaining": {
                          "type": "number",
                          "description": "Same as `balance`"
                        },
                        "api_key_remaining": {
                          "type": "number",
                          "description": "Remaining key quota; equals the account balance when no quota is set"
                        },
                        "total": {
                          "type": "number",
                          "description": "Key quota; `0` means no quota is set"
                        },
                        "used": {
                          "type": "number",
                          "description": "Total amount charged to this key so far"
                        },
                        "unlimited": {
                          "type": "boolean",
                          "description": "`true` when the key has no quota set"
                        },
                        "remaining_cny": {
                          "type": "number",
                          "description": "CNY"
                        },
                        "remaining_usd": {
                          "type": "number",
                          "description": "USD"
                        },
                        "api_key_remaining_cny": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "`null` when no quota is set"
                        },
                        "api_key_remaining_usd": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "`null` when no quota is set"
                        },
                        "total_cny": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "`null` when no quota is set"
                        },
                        "total_usd": {
                          "type": [
                            "number",
                            "null"
                          ],
                          "description": "`null` when no quota is set"
                        },
                        "used_cny": {
                          "type": "number",
                          "description": "CNY"
                        },
                        "used_usd": {
                          "type": "number",
                          "description": "USD"
                        }
                      }
                    },
                    "message": {
                      "type": "string",
                      "description": "Only on anomalies: `api key expired`, `member disabled`, etc."
                    },
                    "group": {
                      "type": "object",
                      "description": "The group this key belongs to; omitted for exclusive groups",
                      "properties": {
                        "id": {
                          "type": "integer",
                          "description": "Group ID"
                        },
                        "name": {
                          "type": "string",
                          "description": "Group name"
                        },
                        "name_i18n": {
                          "type": "object",
                          "additionalProperties": {
                            "type": "string"
                          },
                          "description": "Localized group names keyed by locale code (such as `en`, `zh-tw`, `es`, `ja`), as shown in the console"
                        },
                        "platform": {
                          "type": "string",
                          "description": "The group's protocol family, such as `openai`, `claude`, `gemini`"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "quota": {
                    "summary": "Quota set",
                    "value": {
                      "is_active": true,
                      "balance": 54.4,
                      "remaining": 54.4,
                      "unit": "USD",
                      "ledger_currency": "CNY",
                      "exchange_rate": {
                        "cny_per_usd": 6.8,
                        "basis": "fixed unit rate"
                      },
                      "balance_cny": 54.4,
                      "balance_usd": 8,
                      "quota": {
                        "remaining": 54.4,
                        "api_key_remaining": 54.4,
                        "total": 68,
                        "used": 13.6,
                        "unlimited": false,
                        "remaining_cny": 54.4,
                        "remaining_usd": 8,
                        "api_key_remaining_cny": 54.4,
                        "api_key_remaining_usd": 8,
                        "total_cny": 68,
                        "total_usd": 10,
                        "used_cny": 13.6,
                        "used_usd": 2
                      }
                    }
                  },
                  "expired": {
                    "summary": "Key expired",
                    "value": {
                      "is_active": false,
                      "balance": 0,
                      "message": "api key expired",
                      "ledger_currency": "CNY",
                      "exchange_rate": {
                        "cny_per_usd": 6.8,
                        "basis": "fixed unit rate"
                      },
                      "balance_cny": 0,
                      "balance_usd": 0
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No key sent or not starting with `sk-`: `missing or invalid api key`; key does not exist or is disabled: `invalid api key`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "",
                  "properties": {
                    "is_active": {
                      "const": false
                    },
                    "balance": {
                      "const": 0
                    },
                    "message": {
                      "type": "string",
                      "description": "Error message"
                    }
                  }
                },
                "examples": {
                  "invalid": {
                    "summary": "Invalid key",
                    "value": {
                      "is_active": false,
                      "balance": 0,
                      "message": "invalid api key"
                    }
                  }
                }
              }
            }
          }
        },
        "x-hopbase-slug": "usage",
        "x-hopbase-summary": "Check how much this key can spend right now and its quota; not billed, and a positive balance is not required.",
        "x-hopbase-docs": "https://hop-base.com/zh-cn/docs/api-reference/usage",
        "x-hopbase-scenarios": [
          {
            "id": "quota",
            "label": "Quota set",
            "request": {},
            "response": {
              "status": 200,
              "body": {
                "is_active": true,
                "balance": 54.4,
                "remaining": 54.4,
                "unit": "USD",
                "ledger_currency": "CNY",
                "exchange_rate": {
                  "cny_per_usd": 6.8,
                  "basis": "fixed unit rate"
                },
                "balance_cny": 54.4,
                "balance_usd": 8,
                "quota": {
                  "remaining": 54.4,
                  "api_key_remaining": 54.4,
                  "total": 68,
                  "used": 13.6,
                  "unlimited": false,
                  "remaining_cny": 54.4,
                  "remaining_usd": 8,
                  "api_key_remaining_cny": 54.4,
                  "api_key_remaining_usd": 8,
                  "total_cny": 68,
                  "total_usd": 10,
                  "used_cny": 13.6,
                  "used_usd": 2
                }
              }
            }
          },
          {
            "id": "expired",
            "label": "Key expired",
            "request": {},
            "response": {
              "status": 200,
              "body": {
                "is_active": false,
                "balance": 0,
                "message": "api key expired",
                "ledger_currency": "CNY",
                "exchange_rate": {
                  "cny_per_usd": 6.8,
                  "basis": "fixed unit rate"
                },
                "balance_cny": 0,
                "balance_usd": 0
              }
            }
          },
          {
            "id": "invalid",
            "label": "Invalid key",
            "request": {},
            "response": {
              "status": 401,
              "body": {
                "is_active": false,
                "balance": 0,
                "message": "invalid api key"
              }
            }
          }
        ],
        "x-hopbase-related": [
          {
            "label": "Account and catalog API",
            "href": "/docs/reference/account-api#balance-and-quota"
          },
          {
            "label": "Concurrency, timeouts, and billing",
            "href": "/docs/reference/limits"
          }
        ],
        "x-hopbase-sources": [
          "content/docs/reference/account-api.zh-cn.mdx#balance-and-quota"
        ]
      }
    },
    "/v1/images/tasks": {
      "get": {
        "operationId": "getImageTask",
        "summary": "Get image task",
        "description": "[Create image](https://hop-base.com/zh-cn/docs/api-reference/images-generations) or [Edit image](https://hop-base.com/zh-cn/docs/api-reference/images-edits) with `Prefer: respond-async` returns 202 and a `task_id` immediately; then query it with this endpoint. **The task ID can only go in the `task_id` query parameter, not in the path.**\n\nThe status goes through `pending` / `processing` / `retrying`; the terminal states are `completed` and `failed`. When done, read `result_content`: one line per image, `![image](/assets-runtime/…)`, as a relative path; prepend `https://api.hop-base.com` to access it. The URL **opens without a key**, so do not share it publicly; download it to your own storage soon after completion and do not treat it as long-term storage.\n\nOnly problems found during generation (such as a Gemini reference image failing to download or the model refusing) make the task fail; in that case only an `error` string is returned, with no error code. Submission only checks that the balance is above 0 and reserves nothing; after a terminal state, `usage` shows the actual charge, visible only to the key that created the task.\n\nKling and Midjourney images do not use this endpoint; use [Get video task](https://hop-base.com/zh-cn/docs/api-reference/video-task).",
        "tags": [
          "Images"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "task_id",
            "in": "query",
            "required": true,
            "description": "The `task_id` returned at submission",
            "schema": {
              "type": "string",
              "minLength": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Task object (including failed tasks)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Async image task",
                  "properties": {
                    "task_id": {
                      "type": "string",
                      "description": "Task ID"
                    },
                    "status": {
                      "type": "string",
                      "description": "`pending` / `processing` / `retrying` are in progress; `completed` / `failed` are terminal",
                      "enum": [
                        "pending",
                        "processing",
                        "retrying",
                        "completed",
                        "failed"
                      ]
                    },
                    "result_content": {
                      "type": "string",
                      "description": "Result when done: Markdown, one line per image, `![image](/assets-runtime/…)`. The URL is a relative path; prepend `https://api.hop-base.com` to access it. It opens without a key, so do not share it publicly, and download it soon"
                    },
                    "error": {
                      "type": "string",
                      "description": "Failure reason (an English string, no error code); present only when `failed`"
                    },
                    "usage": {
                      "type": "object",
                      "description": "Present once the task is `completed` or `failed`; visible only to the key that created the task",
                      "properties": {
                        "cost": {
                          "type": "number",
                          "description": "Amount actually deducted from the balance for this task; usually `0` if generation failed, or the actual charge if it failed after billing was settled"
                        },
                        "currency": {
                          "type": "string",
                          "description": "Ledger currency, currently `CNY`"
                        },
                        "cost_cny": {
                          "type": "number",
                          "description": "Amount in CNY (fixed 1 USD = 6.8 CNY), for reconciliation"
                        },
                        "cost_usd": {
                          "type": "number",
                          "description": "Amount in USD, for reconciliation"
                        }
                      }
                    }
                  },
                  "required": [
                    "task_id",
                    "status"
                  ]
                },
                "examples": {
                  "completed": {
                    "summary": "Completed",
                    "value": {
                      "task_id": "imgtask_EXAMPLE",
                      "status": "completed",
                      "result_content": "![image](/assets-runtime/2026/09/xxxxxxxxxxxx.png)",
                      "usage": {
                        "cost": 1.36,
                        "currency": "CNY",
                        "cost_cny": 1.36,
                        "cost_usd": 0.2
                      }
                    }
                  },
                  "processing": {
                    "summary": "In progress",
                    "value": {
                      "task_id": "imgtask_EXAMPLE",
                      "status": "processing"
                    }
                  },
                  "failed": {
                    "summary": "Failed",
                    "value": {
                      "task_id": "imgtask_EXAMPLE",
                      "status": "failed",
                      "error": "<English failure reason>",
                      "usage": {
                        "cost": 0,
                        "currency": "CNY",
                        "cost_cny": 0,
                        "cost_usd": 0
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or expired API key (`missing_api_key` / `invalid_api_key` / `api_key_expired`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-hopbase-slug": "images-task",
        "x-hopbase-summary": "Poll the status and result of async GPT Image / Gemini image tasks (`Prefer: respond-async`).",
        "x-hopbase-docs": "https://hop-base.com/zh-cn/docs/api-reference/images-task",
        "x-hopbase-scenarios": [
          {
            "id": "completed",
            "label": "Completed",
            "request": {
              "query": {
                "task_id": "imgtask_EXAMPLE"
              }
            },
            "response": {
              "status": 200,
              "body": {
                "task_id": "imgtask_EXAMPLE",
                "status": "completed",
                "result_content": "![image](/assets-runtime/2026/09/xxxxxxxxxxxx.png)",
                "usage": {
                  "cost": 1.36,
                  "currency": "CNY",
                  "cost_cny": 1.36,
                  "cost_usd": 0.2
                }
              }
            }
          },
          {
            "id": "processing",
            "label": "In progress",
            "request": {
              "query": {
                "task_id": "imgtask_EXAMPLE"
              }
            },
            "response": {
              "status": 200,
              "body": {
                "task_id": "imgtask_EXAMPLE",
                "status": "processing"
              }
            }
          },
          {
            "id": "failed",
            "label": "Failed",
            "request": {
              "query": {
                "task_id": "imgtask_EXAMPLE"
              }
            },
            "response": {
              "status": 200,
              "body": {
                "task_id": "imgtask_EXAMPLE",
                "status": "failed",
                "error": "<English failure reason>",
                "usage": {
                  "cost": 0,
                  "currency": "CNY",
                  "cost_cny": 0,
                  "cost_usd": 0
                }
              }
            }
          }
        ],
        "x-hopbase-related": [
          {
            "label": "Create image",
            "href": "/docs/api-reference/images-generations"
          },
          {
            "label": "Edit image",
            "href": "/docs/api-reference/images-edits"
          },
          {
            "label": "Async tasks (GPT Image / Gemini)",
            "href": "/docs/media/images#async-tasks-gpt-image--gemini"
          }
        ],
        "x-hopbase-sources": [
          "content/docs/media/images.zh-cn.mdx#异步任务gpt-image--gemini",
          "content/docs/media/images.zh-cn.mdx#计费"
        ]
      }
    },
    "/v1/kling/subjects": {
      "post": {
        "operationId": "createKlingSubject",
        "summary": "Create custom subject",
        "description": "`image_refer` needs one frontal image plus 1–3 supporting reference images; `video_refer` needs one video and can optionally bind a `voice_id`. The fields of the two methods cannot be mixed. Every URL must be a public absolute HTTP(S) address, following the same rules as [Media locators](https://hop-base.com/zh-cn/docs/media/kling#media-locators).\n\nCreation is an async task and is **currently free**. Submission returns 202 and a task `id` (`object` is `kling.subject.task`); poll with [Get video task](https://hop-base.com/zh-cn/docs/api-reference/video-task). When done, the result carries `element_ids` (an array of subject IDs) and `elements` (each with `id`, possibly with `info`).\n\nThe request body is a strict JSON contract: fields outside the table return 400 before the task is created. All field validation happens before submission, so an invalid request never creates a task.",
        "tags": [
          "Video"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Request body for creating a custom subject; only the fields below are accepted.",
                "properties": {
                  "name": {
                    "type": "string",
                    "description": "Subject name; leading and trailing whitespace is trimmed",
                    "minLength": 1,
                    "maxLength": 20
                  },
                  "description": {
                    "type": "string",
                    "description": "Subject description",
                    "maxLength": 100
                  },
                  "reference_type": {
                    "type": "string",
                    "description": "`image_refer` creates from images; `video_refer` creates from one video",
                    "enum": [
                      "image_refer",
                      "video_refer"
                    ]
                  },
                  "frontal_image_url": {
                    "type": "string",
                    "description": "Frontal image URL; required for `image_refer`, not allowed with `video_refer`. Must be a publicly accessible absolute HTTP(S) address",
                    "minLength": 1
                  },
                  "reference_image_urls": {
                    "type": "array",
                    "description": "Supporting reference image URLs; required for `image_refer`, 1–3 of them, none may duplicate the frontal image or each other; not allowed with `video_refer`",
                    "items": {
                      "type": "string",
                      "description": "Reference image URL; must be a publicly accessible absolute HTTP(S) address",
                      "minLength": 1
                    },
                    "minItems": 1,
                    "maxItems": 3,
                    "uniqueItems": true
                  },
                  "video_url": {
                    "type": "string",
                    "description": "Video URL; required for `video_refer`, not allowed with `image_refer`. Must be a publicly accessible absolute HTTP(S) address",
                    "minLength": 1
                  },
                  "voice_id": {
                    "type": "string",
                    "description": "Voice bound to the subject; `video_refer` only"
                  },
                  "tag_ids": {
                    "type": "array",
                    "description": "Tag IDs used to categorize the subject; each must be non-empty and unique",
                    "items": {
                      "type": "string",
                      "description": "Tag ID",
                      "minLength": 1
                    },
                    "uniqueItems": true
                  }
                },
                "required": [
                  "name",
                  "reference_type"
                ],
                "additionalProperties": false
              },
              "examples": {
                "image-refer": {
                  "summary": "From images",
                  "value": {
                    "name": "Orange cat",
                    "description": "Short-haired orange cat with green eyes",
                    "reference_type": "image_refer",
                    "frontal_image_url": "https://cdn.example.com/cat-front.png",
                    "reference_image_urls": [
                      "https://cdn.example.com/cat-side.png",
                      "https://cdn.example.com/cat-back.png"
                    ]
                  }
                },
                "video-refer": {
                  "summary": "From video",
                  "value": {
                    "name": "Host",
                    "reference_type": "video_refer",
                    "video_url": "https://cdn.example.com/host.mp4",
                    "tag_ids": [
                      "your-tag-id"
                    ]
                  }
                },
                "duplicate-image": {
                  "summary": "Duplicate reference image",
                  "value": {
                    "name": "Orange cat",
                    "reference_type": "image_refer",
                    "frontal_image_url": "https://cdn.example.com/cat-front.png",
                    "reference_image_urls": [
                      "https://cdn.example.com/cat-front.png"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Accepted; returns the subject creation task",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Subject creation task accepted",
                  "properties": {
                    "id": {
                      "type": "string",
                      "description": "Task ID; poll it with `GET /v1/video/tasks/{task_id}`"
                    },
                    "object": {
                      "type": "string",
                      "description": "Always `kling.subject.task`"
                    },
                    "status": {
                      "type": "string",
                      "description": "Always `queued`"
                    },
                    "created": {
                      "type": "integer",
                      "description": "Creation time, Unix seconds"
                    }
                  }
                },
                "examples": {
                  "image-refer": {
                    "summary": "From images",
                    "value": {
                      "id": "ktEXAMPLE",
                      "object": "kling.subject.task",
                      "status": "queued",
                      "created": 1790000000
                    }
                  },
                  "video-refer": {
                    "summary": "From video",
                    "value": {
                      "id": "ktEXAMPLE",
                      "object": "kling.subject.task",
                      "status": "queued",
                      "created": 1790000000
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Validation failed before submission; no task is created. Messages include:\n\n`request body does not match the JSON contract: …`: invalid JSON, a field outside the table, or a second JSON value after the request body\n\n`name is required`, `name cannot exceed 20 characters`, `description cannot exceed 100 characters`\n\n`reference_type must be image_refer or video_refer`\n\n`reference_type=image_refer does not accept video_url`, `voice_id is only supported with reference_type=video_refer`, `reference_type=video_refer does not accept image references`\n\n`reference_image_urls must contain 1 to 3 reference images different from the frontal image`, `reference_image_urls[<index>] duplicates the frontal image or another reference image`\n\n`<field> is required`, `<field>.url must be a publicly accessible absolute http(s) URL`\n\n`tag_ids[<index>] cannot be empty`, `tag_ids[<index>] is duplicated`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                },
                "examples": {
                  "duplicate-image": {
                    "summary": "Duplicate reference image",
                    "value": {
                      "error": {
                        "message": "reference_image_urls[0] duplicates the frontal image or another reference image",
                        "type": "invalid_request_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or expired API key (`missing_api_key` / `invalid_api_key` / `api_key_expired`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-hopbase-slug": "kling-subjects-create",
        "x-hopbase-summary": "Create a Kling custom subject from images or a video; put the resulting subject ID in `subjects[].id` of a video request.",
        "x-hopbase-docs": "https://hop-base.com/zh-cn/docs/api-reference/kling-subjects-create",
        "x-hopbase-scenarios": [
          {
            "id": "image-refer",
            "label": "From images",
            "request": {
              "body": {
                "name": "Orange cat",
                "description": "Short-haired orange cat with green eyes",
                "reference_type": "image_refer",
                "frontal_image_url": "https://cdn.example.com/cat-front.png",
                "reference_image_urls": [
                  "https://cdn.example.com/cat-side.png",
                  "https://cdn.example.com/cat-back.png"
                ]
              }
            },
            "response": {
              "status": 202,
              "body": {
                "id": "ktEXAMPLE",
                "object": "kling.subject.task",
                "status": "queued",
                "created": 1790000000
              }
            }
          },
          {
            "id": "video-refer",
            "label": "From video",
            "request": {
              "body": {
                "name": "Host",
                "reference_type": "video_refer",
                "video_url": "https://cdn.example.com/host.mp4",
                "tag_ids": [
                  "your-tag-id"
                ]
              }
            },
            "response": {
              "status": 202,
              "body": {
                "id": "ktEXAMPLE",
                "object": "kling.subject.task",
                "status": "queued",
                "created": 1790000000
              }
            }
          },
          {
            "id": "duplicate-image",
            "label": "Duplicate reference image",
            "request": {
              "body": {
                "name": "Orange cat",
                "reference_type": "image_refer",
                "frontal_image_url": "https://cdn.example.com/cat-front.png",
                "reference_image_urls": [
                  "https://cdn.example.com/cat-front.png"
                ]
              }
            },
            "response": {
              "status": 400,
              "body": {
                "error": {
                  "message": "reference_image_urls[0] duplicates the frontal image or another reference image",
                  "type": "invalid_request_error"
                }
              }
            }
          }
        ],
        "x-hopbase-related": [
          {
            "label": "List custom subjects",
            "href": "/docs/api-reference/kling-subjects-list"
          },
          {
            "label": "Get video task",
            "href": "/docs/api-reference/video-task"
          },
          {
            "label": "Subjects and shots",
            "href": "/docs/media/kling#subjects-and-shots"
          }
        ],
        "x-hopbase-sources": [
          "content/docs/media/kling.zh-cn.mdx#创建自定义主体",
          "content/docs/media/kling.zh-cn.mdx#素材定位",
          "content/docs/media/kling.zh-cn.mdx#任务失败",
          "spec/kling.json#subjects",
          "extensions/airgate-kling/backend/internal/gateway/subjects.go",
          "extensions/airgate-kling/backend/internal/gateway/handlers.go#handleSubjects",
          "extensions/airgate-kling/backend/internal/gateway/tasks.go#taskView"
        ]
      },
      "get": {
        "operationId": "listKlingSubjects",
        "summary": "List custom subjects",
        "description": "Returns the list of existing custom subjects. Takes no query parameters and is not billed.\n\nTo check whether a creation has finished and get the new subject's ID, poll the task ID returned at creation with [Get video task](https://hop-base.com/zh-cn/docs/api-reference/video-task): when done, the result carries `element_ids` and `elements`.",
        "tags": [
          "Video"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Subject list JSON",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Subject list"
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or expired API key (`missing_api_key` / `invalid_api_key` / `api_key_expired`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-hopbase-slug": "kling-subjects-list",
        "x-hopbase-summary": "List the Kling custom subjects you have created.",
        "x-hopbase-docs": "https://hop-base.com/zh-cn/docs/api-reference/kling-subjects-list",
        "x-hopbase-scenarios": [
          {
            "id": "list",
            "label": "List",
            "request": {},
            "response": {
              "status": 200,
              "note": "Returns JSON. Fields follow the actual response; get subject-creation results by querying the video task."
            }
          }
        ],
        "x-hopbase-related": [
          {
            "label": "Create custom subject",
            "href": "/docs/api-reference/kling-subjects-create"
          },
          {
            "label": "Subjects and shots",
            "href": "/docs/media/kling#subjects-and-shots"
          }
        ],
        "x-hopbase-sources": [
          "content/docs/media/kling.zh-cn.mdx#接口",
          "content/docs/media/kling.zh-cn.mdx#创建自定义主体",
          "extensions/airgate-kling/backend/internal/gateway/handlers.go#handleSubjects"
        ]
      }
    },
    "/v1/kling/faces": {
      "post": {
        "operationId": "createKlingFaceSession",
        "summary": "Lip-sync face identification",
        "description": "Synchronous endpoint, **billed per call**. The result contains a session ID and face IDs, valid for 24 hours. In step two, put them in `extra.session_id` and `extra.face_choose` (exactly one item, with `face_id` and `sound_file`) of [Submit video task](https://hop-base.com/zh-cn/docs/api-reference/video-generate); see [Lip sync](https://hop-base.com/zh-cn/docs/media/kling#lip-sync) for the flow.\n\nThe request body accepts only a `videos` array; each item has either `url` or `file_id`, not both, following the same rules as [Media locators](https://hop-base.com/zh-cn/docs/media/kling#media-locators).",
        "tags": [
          "Video"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "Request body for face identification; only `videos` is accepted.",
                "properties": {
                  "videos": {
                    "type": "array",
                    "description": "Media to identify faces in; at least one item",
                    "items": {
                      "type": "object",
                      "description": "Each item must provide exactly one of `url` / `file_id`",
                      "properties": {
                        "url": {
                          "type": "string",
                          "description": "Publicly accessible absolute HTTP(S) address; cannot be an internal, loopback or link-local address, or a URL with credentials"
                        },
                        "file_id": {
                          "type": "string",
                          "description": "File ID of an existing asset"
                        }
                      },
                      "additionalProperties": false
                    },
                    "minItems": 1
                  }
                },
                "required": [
                  "videos"
                ],
                "additionalProperties": false
              },
              "examples": {
                "file-id": {
                  "summary": "Identify",
                  "value": {
                    "videos": [
                      {
                        "file_id": "source-video-file-id"
                      }
                    ]
                  }
                },
                "private-url": {
                  "summary": "Internal address",
                  "value": {
                    "videos": [
                      {
                        "url": "http://127.0.0.1/talk.mp4"
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Identification result JSON with a session ID and face IDs (valid for 24 hours)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Face identification result"
                }
              }
            }
          },
          "400": {
            "description": "Invalid request, not billed. Messages:\n\n`request body does not match the JSON contract: …`: invalid JSON, a field outside the table, or a second JSON value after the request body\n\n`videos is required and must contain at least one item`\n\n`videos[<index>] must provide exactly one of url or file_id`\n\n`videos[<index>].url must be a publicly accessible absolute http(s) URL`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                },
                "examples": {
                  "private-url": {
                    "summary": "Internal address",
                    "value": {
                      "error": {
                        "message": "videos[0].url must be a publicly accessible absolute http(s) URL",
                        "type": "invalid_request_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or expired API key (`missing_api_key` / `invalid_api_key` / `api_key_expired`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-hopbase-slug": "kling-faces",
        "x-hopbase-summary": "Lip sync (`kling-lip-sync`) step one: identify faces in the media and get a session ID and face IDs.",
        "x-hopbase-docs": "https://hop-base.com/zh-cn/docs/api-reference/kling-faces",
        "x-hopbase-scenarios": [
          {
            "id": "file-id",
            "label": "Identify",
            "request": {
              "body": {
                "videos": [
                  {
                    "file_id": "source-video-file-id"
                  }
                ]
              }
            },
            "response": {
              "status": 200,
              "note": "Returns JSON with a session ID and face IDs, valid for 24 hours."
            }
          },
          {
            "id": "private-url",
            "label": "Internal address",
            "request": {
              "body": {
                "videos": [
                  {
                    "url": "http://127.0.0.1/talk.mp4"
                  }
                ]
              }
            },
            "response": {
              "status": 400,
              "body": {
                "error": {
                  "message": "videos[0].url must be a publicly accessible absolute http(s) URL",
                  "type": "invalid_request_error"
                }
              }
            }
          }
        ],
        "x-hopbase-related": [
          {
            "label": "Submit video task",
            "href": "/docs/api-reference/video-generate"
          },
          {
            "label": "Lip sync",
            "href": "/docs/media/kling#lip-sync"
          }
        ],
        "x-hopbase-sources": [
          "content/docs/media/kling.zh-cn.mdx#对口型",
          "content/docs/media/kling.zh-cn.mdx#严格-json-格式",
          "content/docs/media/kling.zh-cn.mdx#素材定位",
          "extensions/airgate-kling/backend/internal/gateway/handlers.go#handleFaceDetect",
          "extensions/airgate-kling/backend/internal/gateway/metadata.go"
        ]
      }
    },
    "/v1/t2a_v2": {
      "post": {
        "operationId": "createT2aV2",
        "summary": "Create T2A v2 audio",
        "description": "Takes the MiniMax T2A v2 request body as is, so official SDK code works after changing the Base URL and key; fields the gateway does not know pass through unchanged, and JSON responses keep the official structure too (except errors). The two speech models belong to their own group, **MiniMax Speech Official**; keys for chat or video groups cannot reach them.\n\nThe gateway does only three things here: validates `model`, the `text` length, `stream` and `output_format`; clamps `voice_setting.speed` to the official range; and limits the request body to ≤1 MiB. Other fields with values outside the official range return 400 from the service.\n\n`data.audio` is hex-encoded audio, and `extra_info.usage_characters` is the billed character count. Pass `stream: true` to switch to SSE: each `data: {...}` event carries a chunk of hex audio, and the final chunk has `data.status` `2` plus `extra_info`. If a stream fails midway, a last event with `base_resp` is pushed before the stream closes, and nothing is billed. See [Streaming](https://hop-base.com/zh-cn/docs/audio/speech#streaming).\n\nFor a cloned voice, set `voice_setting.voice_id` (or `timber_weights[].voice_id`). The clone fee is charged once, with the voice's first successful synthesis, and the usage record details show an extra `voice_clone_activation` item. If you only need the OpenAI shape, use `POST /v1/audio/speech`.",
        "tags": [
          "Speech"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "",
                "properties": {
                  "model": {
                    "type": "string",
                    "description": "Case-sensitive, no aliases",
                    "enum": [
                      "speech-2.8-hd",
                      "speech-2.8-turbo"
                    ]
                  },
                  "text": {
                    "type": "string",
                    "description": "Text to synthesize; separate paragraphs with line breaks. Supports pause markers `<#x#>` (0.01–99.99 seconds), inline pronunciation and interjections; see the [speech guide](https://hop-base.com/zh-cn/docs/audio/speech#native-endpoint). Officially, streaming is recommended beyond 3000 characters",
                    "minLength": 1,
                    "maxLength": 10000
                  },
                  "stream": {
                    "type": "boolean",
                    "description": "When `true`, the response switches to SSE",
                    "default": false
                  },
                  "stream_options": {
                    "type": "object",
                    "description": "Streaming options",
                    "properties": {
                      "exclude_aggregated_audio": {
                        "type": "boolean",
                        "description": "When `true`, the final chunk no longer carries the full audio. Recommended `true` for streaming; otherwise the final chunk resends the whole clip, and appending it directly gives you the audio twice",
                        "default": false
                      }
                    }
                  },
                  "language_boost": {
                    "type": "string",
                    "description": "Improves recognition of that language or dialect; `auto` lets the model decide. Cantonese voices need `Chinese,Yue`. Not set when omitted",
                    "enum": [
                      "auto",
                      "Chinese",
                      "Chinese,Yue",
                      "English",
                      "Arabic",
                      "Russian",
                      "Spanish",
                      "French",
                      "Portuguese",
                      "German",
                      "Turkish",
                      "Dutch",
                      "Ukrainian",
                      "Vietnamese",
                      "Indonesian",
                      "Japanese",
                      "Italian",
                      "Korean",
                      "Thai",
                      "Polish",
                      "Romanian",
                      "Greek",
                      "Czech",
                      "Finnish",
                      "Hindi",
                      "Bulgarian",
                      "Danish",
                      "Hebrew",
                      "Malay",
                      "Persian",
                      "Slovak",
                      "Swedish",
                      "Croatian",
                      "Filipino",
                      "Hungarian",
                      "Norwegian",
                      "Slovenian",
                      "Catalan",
                      "Nynorsk",
                      "Tamil",
                      "Afrikaans"
                    ]
                  },
                  "pronunciation_dict": {
                    "type": "object",
                    "description": "Pronunciation dictionary",
                    "properties": {
                      "tone": {
                        "type": "array",
                        "description": "`source/replacement` rules; multiple rules apply together. The replacement can be plain text (`omg/oh my god`), Japanese kana (a kanji word mapped to its kana reading), pinyin with tones 1–5 in parentheses (a Chinese word mapped to `(chu3)(li3)`) or IPA (`resume/(rɪˈzjuːm)`)",
                        "items": {
                          "type": "string"
                        }
                      }
                    }
                  },
                  "voice_modify": {
                    "type": "object",
                    "description": "Voice modification, passed through with the official semantics; not validated by the gateway",
                    "properties": {
                      "pitch": {
                        "type": "integer",
                        "description": "Deeper → brighter",
                        "minimum": -100,
                        "maximum": 100
                      },
                      "intensity": {
                        "type": "integer",
                        "description": "Stronger → softer",
                        "minimum": -100,
                        "maximum": 100
                      },
                      "timbre": {
                        "type": "integer",
                        "description": "Fuller → crisper",
                        "minimum": -100,
                        "maximum": 100
                      },
                      "sound_effects": {
                        "type": "string",
                        "description": "Sound effect, one at a time. With a sound effect, non-streaming supports `mp3` / `wav` / `flac`, and streaming supports only `mp3`",
                        "enum": [
                          "spacious_echo",
                          "auditorium_echo",
                          "lofi_telephone",
                          "robotic"
                        ]
                      }
                    }
                  },
                  "output_format": {
                    "type": "string",
                    "description": "Only `hex` is supported; `url` returns 400",
                    "enum": [
                      "hex"
                    ],
                    "default": "hex"
                  },
                  "voice_setting": {
                    "type": "object",
                    "description": "Voice settings",
                    "properties": {
                      "voice_id": {
                        "type": "string",
                        "description": "System or cloned voice ID; pass case, spaces and parentheses exactly. See [System voices](https://hop-base.com/zh-cn/docs/audio/speech#system-voices)"
                      },
                      "speed": {
                        "type": "number",
                        "description": "Speed; official range 0.5–2. Values outside the range are clamped into it by the gateway",
                        "default": 1
                      },
                      "vol": {
                        "type": "number",
                        "description": "Volume; greater than 0, up to 10",
                        "exclusiveMinimum": 0,
                        "maximum": 10,
                        "default": 1
                      },
                      "pitch": {
                        "type": "integer",
                        "description": "Pitch; `0` is the original pitch",
                        "minimum": -12,
                        "maximum": 12,
                        "default": 0
                      },
                      "emotion": {
                        "type": "string",
                        "description": "Inferred from the text when omitted; set it only to fix an emotion. Officially, `fluent` and `whisper` are documented only for the 2.6 series; `whisper` is explicitly not supported on Speech 2.8",
                        "enum": [
                          "happy",
                          "sad",
                          "angry",
                          "fearful",
                          "disgusted",
                          "surprised",
                          "calm",
                          "fluent",
                          "whisper"
                        ]
                      },
                      "text_normalization": {
                        "type": "boolean",
                        "description": "Normalizes how Chinese and English numbers are read; adds slight latency",
                        "default": false
                      },
                      "latex_read": {
                        "type": "boolean",
                        "description": "Chinese only; wrap formulas in `$$`. When on, `language_boost` is forced to `Chinese`",
                        "default": false
                      }
                    },
                    "required": [
                      "voice_id"
                    ]
                  },
                  "audio_setting": {
                    "type": "object",
                    "description": "Audio settings",
                    "properties": {
                      "format": {
                        "type": "string",
                        "description": "`opus` is in an Ogg/Opus container",
                        "enum": [
                          "mp3",
                          "pcm",
                          "flac",
                          "wav",
                          "opus"
                        ],
                        "default": "mp3"
                      },
                      "sample_rate": {
                        "type": "integer",
                        "description": "Sample rate; must be set explicitly for `opus`. No official default is documented; the official example uses `32000`",
                        "enum": [
                          8000,
                          16000,
                          22050,
                          24000,
                          32000,
                          44100
                        ]
                      },
                      "bitrate": {
                        "type": "integer",
                        "description": "Bitrate; `mp3` only. No official default is documented; the official example uses `128000`",
                        "enum": [
                          32000,
                          64000,
                          128000,
                          256000
                        ]
                      },
                      "channel": {
                        "type": "integer",
                        "description": "`1` mono, `2` stereo",
                        "enum": [
                          1,
                          2
                        ],
                        "default": 1
                      },
                      "force_cbr": {
                        "type": "boolean",
                        "description": "Constant bitrate; streaming `mp3` only",
                        "default": false
                      }
                    }
                  }
                },
                "required": [
                  "model",
                  "text"
                ]
              },
              "examples": {
                "sync": {
                  "summary": "Synchronous MP3",
                  "value": {
                    "model": "speech-2.8-hd",
                    "text": "Hello, world",
                    "voice_setting": {
                      "voice_id": "Chinese (Mandarin)_News_Anchor",
                      "speed": 1
                    },
                    "audio_setting": {
                      "format": "mp3",
                      "sample_rate": 32000
                    }
                  }
                },
                "stream": {
                  "summary": "SSE streaming",
                  "value": {
                    "model": "speech-2.8-turbo",
                    "text": "Put a longer piece of text here.",
                    "stream": true,
                    "stream_options": {
                      "exclude_aggregated_audio": true
                    },
                    "voice_setting": {
                      "voice_id": "Chinese (Mandarin)_News_Anchor"
                    },
                    "audio_setting": {
                      "format": "mp3",
                      "sample_rate": 32000
                    }
                  }
                },
                "too-long": {
                  "summary": "Text too long",
                  "value": {
                    "model": "speech-2.8-turbo",
                    "text": "(a 10001-character text)",
                    "voice_setting": {
                      "voice_id": "Chinese (Mandarin)_News_Anchor"
                    }
                  }
                },
                "url-format": {
                  "summary": "output_format: url",
                  "value": {
                    "model": "speech-2.8-hd",
                    "text": "Hello",
                    "output_format": "url",
                    "voice_setting": {
                      "voice_id": "Chinese (Mandarin)_News_Anchor"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JSON when non-streaming; `text/event-stream` with `stream: true`, where each event's `data` has the same shape as below",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "",
                  "properties": {
                    "data": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "audio": {
                          "type": "string",
                          "description": "Hex-encoded audio; when streaming, this chunk's audio segment"
                        },
                        "status": {
                          "type": "integer",
                          "description": "`2` on the final streaming chunk"
                        }
                      }
                    },
                    "extra_info": {
                      "type": "object",
                      "description": "Audio metadata and billed character count",
                      "properties": {
                        "usage_characters": {
                          "type": "integer",
                          "description": "Billed character count (authoritative): every Unicode character counts 1 and each Han character counts 1 more; punctuation, spaces, emoji and pause markers count 1 each"
                        },
                        "audio_length": {
                          "type": "integer",
                          "description": "Audio duration, milliseconds"
                        },
                        "audio_sample_rate": {
                          "type": "integer",
                          "description": "Sample rate"
                        },
                        "audio_size": {
                          "type": "integer",
                          "description": "Audio size in bytes"
                        },
                        "bitrate": {
                          "type": "integer",
                          "description": "Bitrate"
                        },
                        "word_count": {
                          "type": "integer",
                          "description": "Word count"
                        },
                        "audio_format": {
                          "type": "string",
                          "description": "Audio format, such as `mp3`"
                        },
                        "audio_channel": {
                          "type": "integer",
                          "description": "Number of channels"
                        }
                      }
                    },
                    "base_resp": {
                      "type": "object",
                      "description": "`{\"status_code\": 0, \"status_msg\": \"success\"}` on success; errors do not come here but as a non-200 status code with an `error` object",
                      "properties": {
                        "status_code": {
                          "type": "integer",
                          "description": "`0` on success"
                        },
                        "status_msg": {
                          "type": "string",
                          "description": "`success` on success"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "sync": {
                    "summary": "Synchronous MP3",
                    "value": {
                      "data": {
                        "audio": "4944330400000000...",
                        "status": 2
                      },
                      "extra_info": {
                        "audio_length": 1320,
                        "audio_sample_rate": 32000,
                        "audio_size": 21645,
                        "bitrate": 128000,
                        "word_count": 5,
                        "usage_characters": 9,
                        "audio_format": "mp3",
                        "audio_channel": 1
                      },
                      "base_resp": {
                        "status_code": 0,
                        "status_msg": "success"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Unsupported `model`, empty `text` or over 10000 characters, `output_format` other than `hex`, nonexistent voice ID, `opus` without `sample_rate`, values outside the official range, sensitive content, etc.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                },
                "examples": {
                  "too-long": {
                    "summary": "Text too long",
                    "value": {
                      "error": {
                        "message": "text exceeds the 10000 character limit (got 10001 characters)",
                        "type": "invalid_request_error"
                      }
                    }
                  },
                  "url-format": {
                    "summary": "output_format: url",
                    "value": {
                      "error": {
                        "message": "output_format \"url\" is not supported; only hex is supported",
                        "type": "invalid_request_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or expired API key (`missing_api_key` / `invalid_api_key` / `api_key_expired`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Balance, or key / member / department quota, exhausted (`insufficient_quota`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "The model is not in this key's group (`model_not_found`), or the path does not belong to the group (`route_not_found`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "Request body over 1 MiB: `request body exceeds the 1048576 byte limit (got N bytes)`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Account or key concurrency cap reached (`user_concurrency_limit` / `apikey_concurrency_limit`), with `Retry-After`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "Audio over 64 MiB (`response_size_limit_exceeded`): use `stream: true`, shorten the text or lower the bitrate",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "No service currently available: back off and retry (2 s, 5 s, 15 s, up to three times)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-hopbase-slug": "t2a-v2",
        "x-hopbase-summary": "MiniMax T2A v2 native request body: full parameters, cloned voices and SSE streaming; audio in JSON responses is hex.",
        "x-hopbase-docs": "https://hop-base.com/zh-cn/docs/api-reference/t2a-v2",
        "x-hopbase-scenarios": [
          {
            "id": "sync",
            "label": "Synchronous MP3",
            "request": {
              "body": {
                "model": "speech-2.8-hd",
                "text": "Hello, world",
                "voice_setting": {
                  "voice_id": "Chinese (Mandarin)_News_Anchor",
                  "speed": 1
                },
                "audio_setting": {
                  "format": "mp3",
                  "sample_rate": 32000
                }
              }
            },
            "response": {
              "status": 200,
              "body": {
                "data": {
                  "audio": "4944330400000000...",
                  "status": 2
                },
                "extra_info": {
                  "audio_length": 1320,
                  "audio_sample_rate": 32000,
                  "audio_size": 21645,
                  "bitrate": 128000,
                  "word_count": 5,
                  "usage_characters": 9,
                  "audio_format": "mp3",
                  "audio_channel": 1
                },
                "base_resp": {
                  "status_code": 0,
                  "status_msg": "success"
                }
              }
            }
          },
          {
            "id": "stream",
            "label": "SSE streaming",
            "request": {
              "stream": true,
              "body": {
                "model": "speech-2.8-turbo",
                "text": "Put a longer piece of text here.",
                "stream": true,
                "stream_options": {
                  "exclude_aggregated_audio": true
                },
                "voice_setting": {
                  "voice_id": "Chinese (Mandarin)_News_Anchor"
                },
                "audio_setting": {
                  "format": "mp3",
                  "sample_rate": 32000
                }
              }
            },
            "response": {
              "status": 200,
              "contentType": "text/event-stream",
              "text": "data: {\"data\":{\"audio\":\"4944330400000000...\",\"status\":1}}\n\ndata: {\"data\":{\"audio\":\"fffb94c400000000...\",\"status\":1}}\n\ndata: {\"data\":{\"audio\":\"\",\"status\":2},\"extra_info\":{\"audio_length\":2616,\"audio_sample_rate\":32000,\"audio_size\":42669,\"bitrate\":128000,\"word_count\":10,\"usage_characters\":21,\"audio_format\":\"mp3\",\"audio_channel\":1},\"base_resp\":{\"status_code\":0,\"status_msg\":\"success\"}}"
            }
          },
          {
            "id": "too-long",
            "label": "Text too long",
            "request": {
              "body": {
                "model": "speech-2.8-turbo",
                "text": "(a 10001-character text)",
                "voice_setting": {
                  "voice_id": "Chinese (Mandarin)_News_Anchor"
                }
              }
            },
            "response": {
              "status": 400,
              "body": {
                "error": {
                  "message": "text exceeds the 10000 character limit (got 10001 characters)",
                  "type": "invalid_request_error"
                }
              }
            }
          },
          {
            "id": "url-format",
            "label": "output_format: url",
            "request": {
              "body": {
                "model": "speech-2.8-hd",
                "text": "Hello",
                "output_format": "url",
                "voice_setting": {
                  "voice_id": "Chinese (Mandarin)_News_Anchor"
                }
              }
            },
            "response": {
              "status": 400,
              "body": {
                "error": {
                  "message": "output_format \"url\" is not supported; only hex is supported",
                  "type": "invalid_request_error"
                }
              }
            }
          }
        ],
        "x-hopbase-related": [
          {
            "label": "Speech guide (voices, streaming, cloning, billing)",
            "href": "/docs/audio/speech"
          },
          {
            "label": "Create speech (OpenAI-compatible)",
            "href": "/docs/api-reference/audio-speech"
          },
          {
            "label": "Concurrency, timeouts, and billing",
            "href": "/docs/reference/limits"
          }
        ],
        "x-hopbase-sources": [
          "content/docs/audio/speech.zh-cn.mdx#原生入口",
          "content/docs/audio/speech.zh-cn.mdx#流式输出",
          "content/docs/audio/speech.zh-cn.mdx#错误与建议",
          "content/docs/reference/limits.zh-cn.mdx#请求体大小",
          "extensions/airgate-minimax/backend/internal/gateway/tts.go"
        ]
      }
    },
    "/v1/files/upload": {
      "post": {
        "operationId": "uploadVoiceFile",
        "summary": "Upload clone audio",
        "description": "Submitted as `multipart/form-data` with only the `purpose` and `file` fields; any other field returns 400. `voice_clone` is the recording to clone, and `prompt_audio` is an optional example clip. Format and size are checked at upload; duration (`voice_clone` 10 seconds to 5 minutes, `prompt_audio` under 8 seconds) is checked when you clone.\n\nFiles are single-use: a successful clone automatically deletes both the source audio and the example audio; a failed clone keeps them so you can retry with other parameters. Files not used within 24 hours of upload are deleted automatically. Uploaded audio cannot be downloaded. The key's group must include the MiniMax Speech models.\n\nClone only your own voice, or one whose speaker has given you explicit written permission.",
        "tags": [
          "Speech"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "description": "",
                "properties": {
                  "purpose": {
                    "type": "string",
                    "description": "`voice_clone` for the recording to clone, `prompt_audio` for an example clip",
                    "enum": [
                      "voice_clone",
                      "prompt_audio"
                    ]
                  },
                  "file": {
                    "type": "string",
                    "description": "One file with extension `.mp3` / `.m4a` / `.wav`, ≤20 MB",
                    "format": "binary"
                  }
                },
                "required": [
                  "purpose",
                  "file"
                ],
                "additionalProperties": false
              },
              "examples": {
                "voice-clone": {
                  "summary": "Upload recording",
                  "value": {
                    "purpose": "voice_clone",
                    "file": "@my_voice.mp3"
                  }
                },
                "prompt-audio": {
                  "summary": "Upload example clip",
                  "value": {
                    "purpose": "prompt_audio",
                    "file": "@prompt.wav"
                  }
                },
                "bad-format": {
                  "summary": "Unsupported format",
                  "value": {
                    "purpose": "voice_clone",
                    "file": "@my_voice.ogg"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Uploaded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "",
                  "properties": {
                    "file": {
                      "type": "object",
                      "description": "Uploaded file",
                      "properties": {
                        "file_id": {
                          "type": "integer",
                          "description": "File ID; pass it as `file_id` or `clone_prompt.prompt_audio` when cloning"
                        },
                        "bytes": {
                          "type": "integer",
                          "description": "File size in bytes"
                        },
                        "created_at": {
                          "type": "integer",
                          "description": "Upload time, Unix seconds"
                        },
                        "filename": {
                          "type": "string",
                          "description": "File name"
                        },
                        "purpose": {
                          "type": "string",
                          "description": "`voice_clone` or `prompt_audio`",
                          "enum": [
                            "voice_clone",
                            "prompt_audio"
                          ]
                        }
                      }
                    },
                    "base_resp": {
                      "type": "object",
                      "description": "`{\"status_code\": 0, \"status_msg\": \"success\"}` on success; errors do not come here but as a non-200 status code with an `error` object",
                      "properties": {
                        "status_code": {
                          "type": "integer",
                          "description": "`0` on success"
                        },
                        "status_msg": {
                          "type": "string",
                          "description": "`success` on success"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "voice-clone": {
                    "summary": "Upload recording",
                    "value": {
                      "file": {
                        "file_id": 123456789,
                        "bytes": 1048576,
                        "created_at": 1790380800,
                        "filename": "my_voice.mp3",
                        "purpose": "voice_clone"
                      },
                      "base_resp": {
                        "status_code": 0,
                        "status_msg": "success"
                      }
                    }
                  },
                  "prompt-audio": {
                    "summary": "Upload example clip",
                    "value": {
                      "file": {
                        "file_id": 123456790,
                        "bytes": 256000,
                        "created_at": 1790380860,
                        "filename": "prompt.wav",
                        "purpose": "prompt_audio"
                      },
                      "base_resp": {
                        "status_code": 0,
                        "status_msg": "success"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "Invalid `purpose`, empty file, unsupported format, or an extra file or field",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                },
                "examples": {
                  "bad-format": {
                    "summary": "Unsupported format",
                    "value": {
                      "error": {
                        "message": "unsupported file format; use mp3, m4a or wav",
                        "type": "invalid_request_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or expired API key (`missing_api_key` / `invalid_api_key` / `api_key_expired`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "The model is not in this key's group (`model_not_found`), or the path does not belong to the group (`route_not_found`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "Request body too large: `file exceeds the 20 MiB limit`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-hopbase-slug": "files-upload",
        "x-hopbase-summary": "Cloning flow step 1: upload a recording or example clip to get a single-use `file_id`; free.",
        "x-hopbase-docs": "https://hop-base.com/zh-cn/docs/api-reference/files-upload",
        "x-hopbase-scenarios": [
          {
            "id": "voice-clone",
            "label": "Upload recording",
            "request": {
              "form": {
                "purpose": "voice_clone",
                "file": "@my_voice.mp3"
              }
            },
            "response": {
              "status": 200,
              "body": {
                "file": {
                  "file_id": 123456789,
                  "bytes": 1048576,
                  "created_at": 1790380800,
                  "filename": "my_voice.mp3",
                  "purpose": "voice_clone"
                },
                "base_resp": {
                  "status_code": 0,
                  "status_msg": "success"
                }
              }
            }
          },
          {
            "id": "prompt-audio",
            "label": "Upload example clip",
            "request": {
              "form": {
                "purpose": "prompt_audio",
                "file": "@prompt.wav"
              }
            },
            "response": {
              "status": 200,
              "body": {
                "file": {
                  "file_id": 123456790,
                  "bytes": 256000,
                  "created_at": 1790380860,
                  "filename": "prompt.wav",
                  "purpose": "prompt_audio"
                },
                "base_resp": {
                  "status_code": 0,
                  "status_msg": "success"
                }
              }
            }
          },
          {
            "id": "bad-format",
            "label": "Unsupported format",
            "request": {
              "form": {
                "purpose": "voice_clone",
                "file": "@my_voice.ogg"
              }
            },
            "response": {
              "status": 400,
              "body": {
                "error": {
                  "message": "unsupported file format; use mp3, m4a or wav",
                  "type": "invalid_request_error"
                }
              }
            }
          }
        ],
        "x-hopbase-related": [
          {
            "label": "Voice cloning",
            "href": "/docs/audio/speech#voice-cloning"
          },
          {
            "label": "Clone voice",
            "href": "/docs/api-reference/clone-voice"
          }
        ],
        "x-hopbase-sources": [
          "content/docs/audio/speech.zh-cn.mdx#1-上传音频",
          "extensions/airgate-minimax/backend/internal/gateway/voice_clone.go"
        ]
      }
    },
    "/v1/files/list": {
      "get": {
        "operationId": "listVoiceFiles",
        "summary": "List clone audio",
        "description": "Returns only files you uploaded that have not been used for a clone and have not expired (within 24 hours of upload), filtered by `purpose`. Uploaded audio cannot be downloaded.",
        "tags": [
          "Speech"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "purpose",
            "in": "query",
            "required": true,
            "description": "Purpose of the files to list",
            "schema": {
              "type": "string",
              "enum": [
                "voice_clone",
                "prompt_audio"
              ]
            }
          }
        ],
        "responses": {
          "200": {
            "description": "File list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "",
                  "properties": {
                    "files": {
                      "type": "array",
                      "description": "Files",
                      "items": {
                        "type": "object",
                        "description": "Uploaded file",
                        "properties": {
                          "file_id": {
                            "type": "integer",
                            "description": "File ID; pass it as `file_id` or `clone_prompt.prompt_audio` when cloning"
                          },
                          "bytes": {
                            "type": "integer",
                            "description": "File size in bytes"
                          },
                          "created_at": {
                            "type": "integer",
                            "description": "Upload time, Unix seconds"
                          },
                          "filename": {
                            "type": "string",
                            "description": "File name"
                          },
                          "purpose": {
                            "type": "string",
                            "description": "`voice_clone` or `prompt_audio`",
                            "enum": [
                              "voice_clone",
                              "prompt_audio"
                            ]
                          }
                        }
                      }
                    },
                    "base_resp": {
                      "type": "object",
                      "description": "`{\"status_code\": 0, \"status_msg\": \"success\"}` on success; errors do not come here but as a non-200 status code with an `error` object",
                      "properties": {
                        "status_code": {
                          "type": "integer",
                          "description": "`0` on success"
                        },
                        "status_msg": {
                          "type": "string",
                          "description": "`success` on success"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "list": {
                    "summary": "List recordings",
                    "value": {
                      "files": [
                        {
                          "file_id": 123456789,
                          "bytes": 1048576,
                          "created_at": 1790380800,
                          "filename": "my_voice.mp3",
                          "purpose": "voice_clone"
                        }
                      ],
                      "base_resp": {
                        "status_code": 0,
                        "status_msg": "success"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`purpose must be \"voice_clone\" or \"prompt_audio\"`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                },
                "examples": {
                  "bad-purpose": {
                    "summary": "Invalid purpose",
                    "value": {
                      "error": {
                        "message": "purpose must be \"voice_clone\" or \"prompt_audio\"",
                        "type": "invalid_request_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or expired API key (`missing_api_key` / `invalid_api_key` / `api_key_expired`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "`file lookup is temporarily unavailable; please retry`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-hopbase-slug": "files-list",
        "x-hopbase-summary": "List your uploaded files that are unused and still valid; free.",
        "x-hopbase-docs": "https://hop-base.com/zh-cn/docs/api-reference/files-list",
        "x-hopbase-scenarios": [
          {
            "id": "list",
            "label": "List recordings",
            "request": {
              "query": {
                "purpose": "voice_clone"
              }
            },
            "response": {
              "status": 200,
              "body": {
                "files": [
                  {
                    "file_id": 123456789,
                    "bytes": 1048576,
                    "created_at": 1790380800,
                    "filename": "my_voice.mp3",
                    "purpose": "voice_clone"
                  }
                ],
                "base_resp": {
                  "status_code": 0,
                  "status_msg": "success"
                }
              }
            }
          },
          {
            "id": "bad-purpose",
            "label": "Invalid purpose",
            "request": {
              "query": {
                "purpose": "voice"
              }
            },
            "response": {
              "status": 400,
              "body": {
                "error": {
                  "message": "purpose must be \"voice_clone\" or \"prompt_audio\"",
                  "type": "invalid_request_error"
                }
              }
            }
          }
        ],
        "x-hopbase-related": [
          {
            "label": "Voice cloning",
            "href": "/docs/audio/speech#voice-cloning"
          }
        ],
        "x-hopbase-sources": [
          "content/docs/audio/speech.zh-cn.mdx#声音克隆",
          "extensions/airgate-minimax/backend/internal/gateway/voice_clone.go"
        ]
      }
    },
    "/v1/files/retrieve": {
      "get": {
        "operationId": "retrieveVoiceFile",
        "summary": "Retrieve clone audio",
        "description": "Only returns files you uploaded that are still valid; files already used for a clone or older than 24 hours return 404.",
        "tags": [
          "Speech"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "parameters": [
          {
            "name": "file_id",
            "in": "query",
            "required": true,
            "description": "File ID returned at upload",
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ],
        "responses": {
          "200": {
            "description": "File info",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "",
                  "properties": {
                    "file": {
                      "type": "object",
                      "description": "Uploaded file",
                      "properties": {
                        "file_id": {
                          "type": "integer",
                          "description": "File ID; pass it as `file_id` or `clone_prompt.prompt_audio` when cloning"
                        },
                        "bytes": {
                          "type": "integer",
                          "description": "File size in bytes"
                        },
                        "created_at": {
                          "type": "integer",
                          "description": "Upload time, Unix seconds"
                        },
                        "filename": {
                          "type": "string",
                          "description": "File name"
                        },
                        "purpose": {
                          "type": "string",
                          "description": "`voice_clone` or `prompt_audio`",
                          "enum": [
                            "voice_clone",
                            "prompt_audio"
                          ]
                        }
                      }
                    },
                    "base_resp": {
                      "type": "object",
                      "description": "`{\"status_code\": 0, \"status_msg\": \"success\"}` on success; errors do not come here but as a non-200 status code with an `error` object",
                      "properties": {
                        "status_code": {
                          "type": "integer",
                          "description": "`0` on success"
                        },
                        "status_msg": {
                          "type": "string",
                          "description": "`success` on success"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "ok": {
                    "summary": "Retrieve file",
                    "value": {
                      "file": {
                        "file_id": 123456789,
                        "bytes": 1048576,
                        "created_at": 1790380800,
                        "filename": "my_voice.mp3",
                        "purpose": "voice_clone"
                      },
                      "base_resp": {
                        "status_code": 0,
                        "status_msg": "success"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`file_id must be a positive integer`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or expired API key (`missing_api_key` / `invalid_api_key` / `api_key_expired`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "File does not exist, was already used, or has expired: `file_id N does not exist`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "summary": "File already used",
                    "value": {
                      "error": {
                        "message": "file_id 123456788 does not exist",
                        "type": "invalid_request_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "`file lookup is temporarily unavailable; please retry`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-hopbase-slug": "files-retrieve",
        "x-hopbase-summary": "Retrieve one unused uploaded file by `file_id`; free.",
        "x-hopbase-docs": "https://hop-base.com/zh-cn/docs/api-reference/files-retrieve",
        "x-hopbase-scenarios": [
          {
            "id": "ok",
            "label": "Retrieve file",
            "request": {
              "query": {
                "file_id": 123456789
              }
            },
            "response": {
              "status": 200,
              "body": {
                "file": {
                  "file_id": 123456789,
                  "bytes": 1048576,
                  "created_at": 1790380800,
                  "filename": "my_voice.mp3",
                  "purpose": "voice_clone"
                },
                "base_resp": {
                  "status_code": 0,
                  "status_msg": "success"
                }
              }
            }
          },
          {
            "id": "not-found",
            "label": "File already used",
            "request": {
              "query": {
                "file_id": 123456788
              }
            },
            "response": {
              "status": 404,
              "body": {
                "error": {
                  "message": "file_id 123456788 does not exist",
                  "type": "invalid_request_error"
                }
              }
            }
          }
        ],
        "x-hopbase-related": [
          {
            "label": "Voice cloning",
            "href": "/docs/audio/speech#voice-cloning"
          }
        ],
        "x-hopbase-sources": [
          "content/docs/audio/speech.zh-cn.mdx#声音克隆",
          "extensions/airgate-minimax/backend/internal/gateway/voice_clone.go"
        ]
      }
    },
    "/v1/files/delete": {
      "post": {
        "operationId": "deleteVoiceFile",
        "summary": "Delete clone audio",
        "description": "`file_id` and `purpose` must match the upload. Deleting a file does not affect voices already cloned; a successful clone already deletes the source files automatically, so this is only for cleaning up files you did not use.",
        "tags": [
          "Speech"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "",
                "properties": {
                  "file_id": {
                    "type": "integer",
                    "description": "File ID returned at upload",
                    "minimum": 1
                  },
                  "purpose": {
                    "type": "string",
                    "description": "Purpose used at upload",
                    "enum": [
                      "voice_clone",
                      "prompt_audio"
                    ]
                  }
                },
                "required": [
                  "file_id",
                  "purpose"
                ],
                "additionalProperties": false
              },
              "examples": {
                "ok": {
                  "summary": "Delete file",
                  "value": {
                    "file_id": 123456789,
                    "purpose": "voice_clone"
                  }
                },
                "not-found": {
                  "summary": "File does not exist",
                  "value": {
                    "file_id": 123456788,
                    "purpose": "voice_clone"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "",
                  "properties": {
                    "file_id": {
                      "type": "integer",
                      "description": "ID of the deleted file"
                    },
                    "base_resp": {
                      "type": "object",
                      "description": "`{\"status_code\": 0, \"status_msg\": \"success\"}` on success; errors do not come here but as a non-200 status code with an `error` object",
                      "properties": {
                        "status_code": {
                          "type": "integer",
                          "description": "`0` on success"
                        },
                        "status_msg": {
                          "type": "string",
                          "description": "`success` on success"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "ok": {
                    "summary": "Delete file",
                    "value": {
                      "file_id": 123456789,
                      "base_resp": {
                        "status_code": 0,
                        "status_msg": "success"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`file_id` is not a positive integer, `purpose` is invalid, or an unknown field is present",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or expired API key (`missing_api_key` / `invalid_api_key` / `api_key_expired`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "File does not exist, was already used, has expired, or `purpose` does not match: `file_id N does not exist`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "summary": "File does not exist",
                    "value": {
                      "error": {
                        "message": "file_id 123456788 does not exist",
                        "type": "invalid_request_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "Request body over 64 KiB: `request body is too large`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "`file deletion is temporarily unavailable; please retry`, etc.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-hopbase-slug": "files-delete",
        "x-hopbase-summary": "Delete one unused uploaded file; free, and does not affect voices already cloned.",
        "x-hopbase-docs": "https://hop-base.com/zh-cn/docs/api-reference/files-delete",
        "x-hopbase-scenarios": [
          {
            "id": "ok",
            "label": "Delete file",
            "request": {
              "body": {
                "file_id": 123456789,
                "purpose": "voice_clone"
              }
            },
            "response": {
              "status": 200,
              "body": {
                "file_id": 123456789,
                "base_resp": {
                  "status_code": 0,
                  "status_msg": "success"
                }
              }
            }
          },
          {
            "id": "not-found",
            "label": "File does not exist",
            "request": {
              "body": {
                "file_id": 123456788,
                "purpose": "voice_clone"
              }
            },
            "response": {
              "status": 404,
              "body": {
                "error": {
                  "message": "file_id 123456788 does not exist",
                  "type": "invalid_request_error"
                }
              }
            }
          }
        ],
        "x-hopbase-related": [
          {
            "label": "Voice cloning",
            "href": "/docs/audio/speech#voice-cloning"
          }
        ],
        "x-hopbase-sources": [
          "content/docs/audio/speech.zh-cn.mdx#声音克隆",
          "extensions/airgate-minimax/backend/internal/gateway/voice_clone.go"
        ]
      }
    },
    "/v1/voice_clone": {
      "post": {
        "operationId": "createVoiceClone",
        "summary": "Create a cloned voice",
        "description": "Pass the `file_id` from step 1 and a `voice_id` you choose; then put the `voice_id` in `voice` on `/v1/audio/speech` or `voice_setting.voice_id` on `/v1/t2a_v2` to synthesize. Add `text` and `model` to get a preview clip: `demo_audio` is a download link on api.hop-base.com, valid for 6 hours; it is empty without `text`.\n\n**Billing**: uploading and cloning are free. The clone fee is charged once, with the voice's first successful synthesis (the usage record details show an extra `voice_clone_activation` item); the preview is billed only as speech characters and does not count as first use. Prices are on the [pricing page](https://hop-base.com/pricing).\n\n**Lifecycle**: a successful clone automatically deletes the source audio and the example audio, so upload again to clone again; a failed clone keeps the files so you can retry with other parameters. A voice not used for synthesis within 7 days of cloning is deleted automatically, and no clone fee is charged. Voices belong only to your account (on an enterprise account, shared by the member keys under the owner); other accounts cannot use them even if they know the `voice_id`.",
        "tags": [
          "Speech"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "",
                "properties": {
                  "file_id": {
                    "type": "integer",
                    "description": "File ID returned by the step 1 upload with `purpose=voice_clone`; single-use",
                    "minimum": 1
                  },
                  "voice_id": {
                    "type": "string",
                    "description": "A voice name you choose, unique within your account: letters, digits, `-` and `_`, starting with a letter and not ending with `-` or `_`",
                    "minLength": 8,
                    "maxLength": 256,
                    "pattern": "^[A-Za-z](?:[A-Za-z0-9_-]*[A-Za-z0-9])?$"
                  },
                  "clone_prompt": {
                    "type": "object",
                    "description": "Example clip",
                    "properties": {
                      "prompt_audio": {
                        "type": "integer",
                        "description": "File ID returned by an upload with `purpose=prompt_audio`",
                        "minimum": 1
                      },
                      "prompt_text": {
                        "type": "string",
                        "description": "Exact transcript of the example clip, ending with punctuation"
                      }
                    },
                    "required": [
                      "prompt_audio",
                      "prompt_text"
                    ]
                  },
                  "text": {
                    "type": "string",
                    "description": "Preview text; when set, a preview clip is returned, billed as speech characters (does not count as first use)",
                    "maxLength": 1000
                  },
                  "model": {
                    "type": "string",
                    "description": "Required when `text` is set",
                    "enum": [
                      "speech-2.8-hd",
                      "speech-2.8-turbo"
                    ]
                  },
                  "language_boost": {
                    "type": "string",
                    "description": "Same as the native endpoint",
                    "enum": [
                      "auto",
                      "Chinese",
                      "Chinese,Yue",
                      "English",
                      "Arabic",
                      "Russian",
                      "Spanish",
                      "French",
                      "Portuguese",
                      "German",
                      "Turkish",
                      "Dutch",
                      "Ukrainian",
                      "Vietnamese",
                      "Indonesian",
                      "Japanese",
                      "Italian",
                      "Korean",
                      "Thai",
                      "Polish",
                      "Romanian",
                      "Greek",
                      "Czech",
                      "Finnish",
                      "Hindi",
                      "Bulgarian",
                      "Danish",
                      "Hebrew",
                      "Malay",
                      "Persian",
                      "Slovak",
                      "Swedish",
                      "Croatian",
                      "Filipino",
                      "Hungarian",
                      "Norwegian",
                      "Slovenian",
                      "Catalan",
                      "Nynorsk",
                      "Tamil",
                      "Afrikaans"
                    ]
                  },
                  "text_validation": {
                    "type": "string",
                    "description": "Expected transcript; checked against the source audio with speech recognition",
                    "maxLength": 200
                  },
                  "accuracy": {
                    "type": "number",
                    "description": "Pass threshold for `text_validation`; official default `0.7`",
                    "minimum": 0,
                    "maximum": 1
                  },
                  "need_noise_reduction": {
                    "type": "boolean",
                    "description": "Noise reduction",
                    "default": false
                  },
                  "need_volume_normalization": {
                    "type": "boolean",
                    "description": "Volume normalization",
                    "default": false
                  },
                  "aigc_watermark": {
                    "type": "boolean",
                    "description": "AIGC watermark",
                    "default": false
                  }
                },
                "required": [
                  "file_id",
                  "voice_id"
                ],
                "additionalProperties": false
              },
              "examples": {
                "preview": {
                  "summary": "Clone with preview",
                  "value": {
                    "file_id": 123456789,
                    "voice_id": "MyNarrator01",
                    "text": "Hello, this is my cloned voice.",
                    "model": "speech-2.8-hd",
                    "need_noise_reduction": true
                  }
                },
                "prompt": {
                  "summary": "With example clip",
                  "value": {
                    "file_id": 123456789,
                    "voice_id": "MyNarrator02",
                    "clone_prompt": {
                      "prompt_audio": 123456790,
                      "prompt_text": "What lovely weather today."
                    }
                  }
                },
                "file-used": {
                  "summary": "File already used",
                  "value": {
                    "file_id": 123456789,
                    "voice_id": "MyNarrator03"
                  }
                },
                "voice-exists": {
                  "summary": "Voice name already taken",
                  "value": {
                    "file_id": 123456791,
                    "voice_id": "MyNarrator01"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Clone succeeded",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "",
                  "properties": {
                    "input_sensitive": {
                      "type": "boolean",
                      "description": "Whether the input triggered sensitive content"
                    },
                    "input_sensitive_type": {
                      "type": "integer",
                      "description": "Sensitive content type"
                    },
                    "demo_audio": {
                      "type": "string",
                      "description": "Preview audio download link, valid for 6 hours; empty string without `text`"
                    },
                    "extra_info": {
                      "type": "object",
                      "description": "Returned only with a preview",
                      "properties": {
                        "usage_characters": {
                          "type": "integer",
                          "description": "Billed preview characters"
                        },
                        "audio_length": {
                          "type": "integer",
                          "description": "Preview audio duration, milliseconds"
                        }
                      }
                    },
                    "base_resp": {
                      "type": "object",
                      "description": "`{\"status_code\": 0, \"status_msg\": \"success\"}` on success; errors do not come here but as a non-200 status code with an `error` object",
                      "properties": {
                        "status_code": {
                          "type": "integer",
                          "description": "`0` on success"
                        },
                        "status_msg": {
                          "type": "string",
                          "description": "`success` on success"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "preview": {
                    "summary": "Clone with preview",
                    "value": {
                      "input_sensitive": false,
                      "input_sensitive_type": 0,
                      "demo_audio": "https://api.hop-base.com/relay/EXAMPLE-TOKEN",
                      "extra_info": {
                        "audio_length": 2210,
                        "usage_characters": 31
                      },
                      "base_resp": {
                        "status_code": 0,
                        "status_msg": "success"
                      }
                    }
                  },
                  "prompt": {
                    "summary": "With example clip",
                    "value": {
                      "input_sensitive": false,
                      "input_sensitive_type": 0,
                      "demo_audio": "",
                      "base_resp": {
                        "status_code": 0,
                        "status_msg": "success"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`file_id` already used or expired, invalid or taken `voice_id`, audio duration out of range, `text_validation` check failed, `text` too long, `text` without `model`, unknown fields, etc.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                },
                "examples": {
                  "file-used": {
                    "summary": "File already used",
                    "value": {
                      "error": {
                        "message": "file_id 123456789 does not exist; uploaded files are single-use and expire 24 hours after upload, please upload the audio again",
                        "type": "invalid_request_error"
                      }
                    }
                  },
                  "voice-exists": {
                    "summary": "Voice name already taken",
                    "value": {
                      "error": {
                        "message": "voice_id \"MyNarrator01\" already exists; choose another voice_id or delete the existing voice first",
                        "type": "invalid_request_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or expired API key (`missing_api_key` / `invalid_api_key` / `api_key_expired`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "402": {
            "description": "Balance, or key / member / department quota, exhausted (`insufficient_quota`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "The model is not in this key's group (`model_not_found`), or the path does not belong to the group (`route_not_found`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "Request body over 64 KiB: `request body is too large`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "`voice cloning is temporarily unavailable`, `voice registry is temporarily unavailable; please retry`, etc.: retry later",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-hopbase-slug": "clone-voice",
        "x-hopbase-summary": "Cloning flow step 2: clone a voice you name from the uploaded recording; cloning itself is free, and the clone fee is charged once with the first successful synthesis.",
        "x-hopbase-docs": "https://hop-base.com/zh-cn/docs/api-reference/clone-voice",
        "x-hopbase-scenarios": [
          {
            "id": "preview",
            "label": "Clone with preview",
            "request": {
              "body": {
                "file_id": 123456789,
                "voice_id": "MyNarrator01",
                "text": "Hello, this is my cloned voice.",
                "model": "speech-2.8-hd",
                "need_noise_reduction": true
              }
            },
            "response": {
              "status": 200,
              "body": {
                "input_sensitive": false,
                "input_sensitive_type": 0,
                "demo_audio": "https://api.hop-base.com/relay/EXAMPLE-TOKEN",
                "extra_info": {
                  "audio_length": 2210,
                  "usage_characters": 31
                },
                "base_resp": {
                  "status_code": 0,
                  "status_msg": "success"
                }
              }
            }
          },
          {
            "id": "prompt",
            "label": "With example clip",
            "request": {
              "body": {
                "file_id": 123456789,
                "voice_id": "MyNarrator02",
                "clone_prompt": {
                  "prompt_audio": 123456790,
                  "prompt_text": "What lovely weather today."
                }
              }
            },
            "response": {
              "status": 200,
              "body": {
                "input_sensitive": false,
                "input_sensitive_type": 0,
                "demo_audio": "",
                "base_resp": {
                  "status_code": 0,
                  "status_msg": "success"
                }
              }
            }
          },
          {
            "id": "file-used",
            "label": "File already used",
            "request": {
              "body": {
                "file_id": 123456789,
                "voice_id": "MyNarrator03"
              }
            },
            "response": {
              "status": 400,
              "body": {
                "error": {
                  "message": "file_id 123456789 does not exist; uploaded files are single-use and expire 24 hours after upload, please upload the audio again",
                  "type": "invalid_request_error"
                }
              }
            }
          },
          {
            "id": "voice-exists",
            "label": "Voice name already taken",
            "request": {
              "body": {
                "file_id": 123456791,
                "voice_id": "MyNarrator01"
              }
            },
            "response": {
              "status": 400,
              "body": {
                "error": {
                  "message": "voice_id \"MyNarrator01\" already exists; choose another voice_id or delete the existing voice first",
                  "type": "invalid_request_error"
                }
              }
            }
          }
        ],
        "x-hopbase-related": [
          {
            "label": "Voice cloning",
            "href": "/docs/audio/speech#voice-cloning"
          },
          {
            "label": "Upload clone audio",
            "href": "/docs/api-reference/files-upload"
          },
          {
            "label": "Speech billing",
            "href": "/docs/audio/speech#billing"
          }
        ],
        "x-hopbase-sources": [
          "content/docs/audio/speech.zh-cn.mdx#2-克隆音色",
          "content/docs/audio/speech.zh-cn.mdx#计费",
          "extensions/airgate-minimax/backend/internal/gateway/voice_clone.go"
        ]
      }
    },
    "/v1/get_voice": {
      "post": {
        "operationId": "getVoices",
        "summary": "List voices",
        "description": "`voice_type` `voice_cloning` lists your cloned voices, `system` lists system voices, and `all` lists everything; `voice_generation` is always empty. Categories you did not request are `null` in the response.\n\nCloned voices include only voices in your account that were cloned successfully and have not been deleted or expired. You can also see system voices in [System voices](https://hop-base.com/zh-cn/docs/audio/speech#system-voices).",
        "tags": [
          "Speech"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "",
                "properties": {
                  "voice_type": {
                    "type": "string",
                    "description": "Voice category to list",
                    "enum": [
                      "system",
                      "voice_cloning",
                      "voice_generation",
                      "all"
                    ]
                  }
                },
                "required": [
                  "voice_type"
                ],
                "additionalProperties": false
              },
              "examples": {
                "cloning": {
                  "summary": "Clone voice",
                  "value": {
                    "voice_type": "voice_cloning"
                  }
                },
                "bad-type": {
                  "summary": "Invalid voice_type",
                  "value": {
                    "voice_type": "cloned"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Voice list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "",
                  "properties": {
                    "system_voice": {
                      "type": [
                        "array",
                        "null"
                      ],
                      "items": {
                        "type": "object"
                      },
                      "description": "System voices; `null` if not requested"
                    },
                    "voice_cloning": {
                      "type": [
                        "array",
                        "null"
                      ],
                      "items": {
                        "type": "object",
                        "description": "Clone voice",
                        "properties": {
                          "voice_id": {
                            "type": "string",
                            "description": "The voice name you chose"
                          },
                          "description": {
                            "type": "array",
                            "description": "Always an empty array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "created_time": {
                            "type": "string",
                            "description": "Creation date, `YYYY-MM-DD` (UTC)"
                          }
                        }
                      },
                      "description": "Your cloned voices; `null` if not requested"
                    },
                    "voice_generation": {
                      "type": [
                        "array",
                        "null"
                      ],
                      "items": {
                        "type": "object"
                      },
                      "description": "Always an empty array; `null` if not requested"
                    },
                    "base_resp": {
                      "type": "object",
                      "description": "`{\"status_code\": 0, \"status_msg\": \"success\"}` on success; errors do not come here but as a non-200 status code with an `error` object",
                      "properties": {
                        "status_code": {
                          "type": "integer",
                          "description": "`0` on success"
                        },
                        "status_msg": {
                          "type": "string",
                          "description": "`success` on success"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "cloning": {
                    "summary": "Clone voice",
                    "value": {
                      "system_voice": null,
                      "voice_cloning": [
                        {
                          "voice_id": "MyNarrator01",
                          "description": [],
                          "created_time": "2026-09-25"
                        }
                      ],
                      "voice_generation": null,
                      "base_resp": {
                        "status_code": 0,
                        "status_msg": "success"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`voice_type must be one of system, voice_cloning, voice_generation, all`, or an unknown field is present",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                },
                "examples": {
                  "bad-type": {
                    "summary": "Invalid voice_type",
                    "value": {
                      "error": {
                        "message": "voice_type must be one of system, voice_cloning, voice_generation, all",
                        "type": "invalid_request_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or expired API key (`missing_api_key` / `invalid_api_key` / `api_key_expired`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "Request body over 64 KiB: `request body is too large`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Voice or file registry temporarily unavailable; retry later (e.g. `voice registry is temporarily unavailable; please retry`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-hopbase-slug": "get-voice",
        "x-hopbase-summary": "List system voices or your cloned voices; free.",
        "x-hopbase-docs": "https://hop-base.com/zh-cn/docs/api-reference/get-voice",
        "x-hopbase-scenarios": [
          {
            "id": "cloning",
            "label": "Clone voice",
            "request": {
              "body": {
                "voice_type": "voice_cloning"
              }
            },
            "response": {
              "status": 200,
              "body": {
                "system_voice": null,
                "voice_cloning": [
                  {
                    "voice_id": "MyNarrator01",
                    "description": [],
                    "created_time": "2026-09-25"
                  }
                ],
                "voice_generation": null,
                "base_resp": {
                  "status_code": 0,
                  "status_msg": "success"
                }
              }
            }
          },
          {
            "id": "bad-type",
            "label": "Invalid voice_type",
            "request": {
              "body": {
                "voice_type": "cloned"
              }
            },
            "response": {
              "status": 400,
              "body": {
                "error": {
                  "message": "voice_type must be one of system, voice_cloning, voice_generation, all",
                  "type": "invalid_request_error"
                }
              }
            }
          }
        ],
        "x-hopbase-related": [
          {
            "label": "Voice cloning",
            "href": "/docs/audio/speech#voice-cloning"
          },
          {
            "label": "System voices",
            "href": "/docs/audio/speech#system-voices"
          }
        ],
        "x-hopbase-sources": [
          "content/docs/audio/speech.zh-cn.mdx#系统音色",
          "content/docs/audio/speech.zh-cn.mdx#声音克隆",
          "extensions/airgate-minimax/backend/internal/gateway/voice_clone.go"
        ]
      }
    },
    "/v1/delete_voice": {
      "post": {
        "operationId": "deleteVoice",
        "summary": "Delete voice",
        "description": "Only cloned voices can be deleted, and `voice_type` is always `voice_cloning`. After deletion, the same `voice_id` can be cloned again; synthesizing with a deleted voice returns 400.",
        "tags": [
          "Speech"
        ],
        "security": [
          {
            "bearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "",
                "properties": {
                  "voice_type": {
                    "type": "string",
                    "description": "Always `voice_cloning`",
                    "enum": [
                      "voice_cloning"
                    ]
                  },
                  "voice_id": {
                    "type": "string",
                    "description": "Name of the cloned voice to delete"
                  }
                },
                "required": [
                  "voice_type",
                  "voice_id"
                ],
                "additionalProperties": false
              },
              "examples": {
                "ok": {
                  "summary": "Delete cloned voice",
                  "value": {
                    "voice_type": "voice_cloning",
                    "voice_id": "MyNarrator01"
                  }
                },
                "not-found": {
                  "summary": "Voice does not exist",
                  "value": {
                    "voice_type": "voice_cloning",
                    "voice_id": "MyNarrator99"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "",
                  "properties": {
                    "voice_id": {
                      "type": "string",
                      "description": "Name of the deleted voice"
                    },
                    "created_time": {
                      "type": "string",
                      "description": "Voice creation time, Unix seconds as a string"
                    },
                    "base_resp": {
                      "type": "object",
                      "description": "`{\"status_code\": 0, \"status_msg\": \"success\"}` on success; errors do not come here but as a non-200 status code with an `error` object",
                      "properties": {
                        "status_code": {
                          "type": "integer",
                          "description": "`0` on success"
                        },
                        "status_msg": {
                          "type": "string",
                          "description": "`success` on success"
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "ok": {
                    "summary": "Delete cloned voice",
                    "value": {
                      "voice_id": "MyNarrator01",
                      "created_time": "1790380920",
                      "base_resp": {
                        "status_code": 0,
                        "status_msg": "success"
                      }
                    }
                  }
                }
              }
            }
          },
          "400": {
            "description": "`voice_type must be \"voice_cloning\"`, `voice_id \"…\" does not exist`, or an unknown field is present",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                },
                "examples": {
                  "not-found": {
                    "summary": "Voice does not exist",
                    "value": {
                      "error": {
                        "message": "voice_id \"MyNarrator99\" does not exist",
                        "type": "invalid_request_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "Missing, invalid or expired API key (`missing_api_key` / `invalid_api_key` / `api_key_expired`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "Request body over 64 KiB: `request body is too large`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "Voice or file registry temporarily unavailable; retry later (e.g. `voice registry is temporarily unavailable; please retry`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "Error response in OpenAI shape. In code, branch on the HTTP status and `code`, never on the message text.",
                  "properties": {
                    "error": {
                      "type": "object",
                      "description": "",
                      "properties": {
                        "message": {
                          "type": "string",
                          "description": "Error message; language follows the `Accept-Language` request header, English by default"
                        },
                        "type": {
                          "type": "string",
                          "description": "For example `invalid_request_error`"
                        },
                        "code": {
                          "type": [
                            "string",
                            "null"
                          ],
                          "description": "Stable error code such as `insufficient_quota` or `model_not_found`; some 400s have no `code`"
                        }
                      },
                      "required": [
                        "message"
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-hopbase-slug": "delete-voice",
        "x-hopbase-summary": "Delete your cloned voice and free its name; free.",
        "x-hopbase-docs": "https://hop-base.com/zh-cn/docs/api-reference/delete-voice",
        "x-hopbase-scenarios": [
          {
            "id": "ok",
            "label": "Delete cloned voice",
            "request": {
              "body": {
                "voice_type": "voice_cloning",
                "voice_id": "MyNarrator01"
              }
            },
            "response": {
              "status": 200,
              "body": {
                "voice_id": "MyNarrator01",
                "created_time": "1790380920",
                "base_resp": {
                  "status_code": 0,
                  "status_msg": "success"
                }
              }
            }
          },
          {
            "id": "not-found",
            "label": "Voice does not exist",
            "request": {
              "body": {
                "voice_type": "voice_cloning",
                "voice_id": "MyNarrator99"
              }
            },
            "response": {
              "status": 400,
              "body": {
                "error": {
                  "message": "voice_id \"MyNarrator99\" does not exist",
                  "type": "invalid_request_error"
                }
              }
            }
          }
        ],
        "x-hopbase-related": [
          {
            "label": "Voice cloning",
            "href": "/docs/audio/speech#voice-cloning"
          },
          {
            "label": "List voices",
            "href": "/docs/api-reference/get-voice"
          }
        ],
        "x-hopbase-sources": [
          "content/docs/audio/speech.zh-cn.mdx#声音克隆",
          "extensions/airgate-minimax/backend/internal/gateway/voice_clone.go"
        ]
      }
    },
    "/api/v1/models/pricing": {
      "get": {
        "operationId": "listModelPricing",
        "summary": "Public model catalog",
        "description": "No key required. Any site may read the response cross-origin, and it is cached for up to 5 minutes (`Cache-Control: public, max-age=300`).\n\nPrices are **USD list prices before the group multiplier**; the price you actually pay for each model is in the signed-in [model catalog](https://api.hop-base.com/models). To see only which models a key can call, use `GET /v1/models`.\n\n`data[].platform` is the protocol family the model is served under (for example `openai`, `claude`, `gemini`, `kling`), not the model vendor; see `vendor` for that. A model offered through several groups may appear under several `platform` values. For field details see [Account and catalog API](https://hop-base.com/zh-cn/docs/reference/account-api#public-model-catalog).",
        "tags": [
          "Account and catalog"
        ],
        "security": [],
        "responses": {
          "200": {
            "description": "Model catalog grouped by protocol family; with `Access-Control-Allow-Origin: *` and `Cache-Control: public, max-age=300`",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "description": "",
                  "properties": {
                    "code": {
                      "type": "integer",
                      "description": "`0` on success"
                    },
                    "message": {
                      "type": "string",
                      "description": "`ok` on success"
                    },
                    "data": {
                      "type": "array",
                      "description": "Grouped by protocol family",
                      "items": {
                        "type": "object",
                        "description": "",
                        "properties": {
                          "platform": {
                            "type": "string",
                            "description": "The protocol family the model is served under, not the model vendor"
                          },
                          "models": {
                            "type": "array",
                            "description": "Models in this protocol family",
                            "items": {
                              "type": "object",
                              "description": "Model entry. Fields may be added in the future; ignore any you do not recognize",
                              "properties": {
                                "id": {
                                  "type": "string",
                                  "description": "The model ID to pass"
                                },
                                "name": {
                                  "type": "string",
                                  "description": "Display name"
                                },
                                "vendor": {
                                  "type": "string",
                                  "description": "Model vendor, such as `openai` or `google`; may be absent"
                                },
                                "series": {
                                  "type": "string",
                                  "description": "Series used by the console to group versions together; may be absent"
                                },
                                "category": {
                                  "type": "string",
                                  "description": "Model category",
                                  "enum": [
                                    "chat",
                                    "image",
                                    "video",
                                    "audio",
                                    "embedding"
                                  ]
                                },
                                "capabilities": {
                                  "type": "array",
                                  "description": "For example `chat`, `reasoning`, `image_generation`, `image_edit`, `video_generation`, `tts`",
                                  "items": {
                                    "type": "string"
                                  }
                                },
                                "context_window": {
                                  "type": "integer",
                                  "description": "Tokens; not returned when unpublished"
                                },
                                "price_unit": {
                                  "type": "string",
                                  "description": "Unit for all prices in this entry: `token` per million tokens, `second` per second of video, `image` per image, `character` per million billed characters",
                                  "enum": [
                                    "token",
                                    "second",
                                    "image",
                                    "character"
                                  ]
                                },
                                "input": {
                                  "type": "number",
                                  "description": "Input price, USD / `price_unit`; speech models use only `input`"
                                },
                                "cached_input": {
                                  "type": "number",
                                  "description": "Cached input price, USD / `price_unit`; absent when caching does not apply"
                                },
                                "output": {
                                  "type": "number",
                                  "description": "Output price, USD / `price_unit`"
                                },
                                "long_context": {
                                  "type": "object",
                                  "description": "Present when there is a long-context tier: when input tokens exceed `threshold`, the whole request is billed with the three multipliers",
                                  "properties": {
                                    "threshold": {
                                      "type": "integer",
                                      "description": "Input token threshold"
                                    },
                                    "input_multiplier": {
                                      "type": "number",
                                      "description": "Input multiplier"
                                    },
                                    "cached_multiplier": {
                                      "type": "number",
                                      "description": "Cached input multiplier"
                                    },
                                    "output_multiplier": {
                                      "type": "number",
                                      "description": "Output multiplier"
                                    }
                                  }
                                },
                                "image": {
                                  "type": "object",
                                  "additionalProperties": {
                                    "type": "number"
                                  },
                                  "description": "Per-image price by resolution tier, for example `{\"1k\": …, \"2k\": …, \"4k\": …}`"
                                },
                                "video_tokens": {
                                  "type": "object",
                                  "description": "Video prices tiered by resolution, audio on/off and reference media on/off. When `price_unit` is `token` they are per million video tokens; when `second`, per second. The key names are kept for historical reasons"
                                }
                              },
                              "required": [
                                "id"
                              ]
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "examples": {
                  "catalog": {
                    "summary": "Chat and speech",
                    "value": {
                      "code": 0,
                      "message": "ok",
                      "data": [
                        {
                          "platform": "openai",
                          "models": [
                            {
                              "id": "gpt-6-astra",
                              "name": "GPT-6 Astra",
                              "context_window": 1050000,
                              "capabilities": [
                                "chat",
                                "reasoning"
                              ],
                              "vendor": "openai",
                              "category": "chat",
                              "input": 10,
                              "cached_input": 1,
                              "output": 50,
                              "long_context": {
                                "threshold": 272000,
                                "input_multiplier": 2,
                                "cached_multiplier": 2,
                                "output_multiplier": 1.5
                              },
                              "price_unit": "token"
                            }
                          ]
                        },
                        {
                          "platform": "minimax",
                          "models": [
                            {
                              "id": "speech-2.8-hd",
                              "name": "MiniMax Speech 2.8 HD",
                              "capabilities": [
                                "tts"
                              ],
                              "vendor": "minimax",
                              "series": "minimax-speech",
                              "category": "audio",
                              "input": 100,
                              "output": 0,
                              "price_unit": "character"
                            }
                          ]
                        }
                      ]
                    }
                  }
                }
              }
            }
          }
        },
        "x-hopbase-slug": "models-pricing",
        "x-hopbase-summary": "Site-wide model catalog with USD list prices, no key required; any site may read it cross-origin, cached for 5 minutes.",
        "x-hopbase-docs": "https://hop-base.com/zh-cn/docs/api-reference/models-pricing",
        "x-hopbase-scenarios": [
          {
            "id": "catalog",
            "label": "Chat and speech",
            "request": {},
            "response": {
              "status": 200,
              "body": {
                "code": 0,
                "message": "ok",
                "data": [
                  {
                    "platform": "openai",
                    "models": [
                      {
                        "id": "gpt-6-astra",
                        "name": "GPT-6 Astra",
                        "context_window": 1050000,
                        "capabilities": [
                          "chat",
                          "reasoning"
                        ],
                        "vendor": "openai",
                        "category": "chat",
                        "input": 10,
                        "cached_input": 1,
                        "output": 50,
                        "long_context": {
                          "threshold": 272000,
                          "input_multiplier": 2,
                          "cached_multiplier": 2,
                          "output_multiplier": 1.5
                        },
                        "price_unit": "token"
                      }
                    ]
                  },
                  {
                    "platform": "minimax",
                    "models": [
                      {
                        "id": "speech-2.8-hd",
                        "name": "MiniMax Speech 2.8 HD",
                        "capabilities": [
                          "tts"
                        ],
                        "vendor": "minimax",
                        "series": "minimax-speech",
                        "category": "audio",
                        "input": 100,
                        "output": 0,
                        "price_unit": "character"
                      }
                    ]
                  }
                ]
              }
            }
          }
        ],
        "x-hopbase-related": [
          {
            "label": "Account and catalog API",
            "href": "/docs/reference/account-api#public-model-catalog"
          },
          {
            "label": "List models",
            "href": "/docs/api-reference/models"
          },
          {
            "label": "Models overview",
            "href": "/docs/models"
          }
        ],
        "x-hopbase-sources": [
          "content/docs/reference/account-api.zh-cn.mdx#public-model-catalog",
          "core/airgate-core/backend/internal/server/handler/plugin_handler_routes.go"
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearer": {
        "type": "http",
        "scheme": "bearer",
        "description": "Authorization: Bearer sk-... (accepted by every endpoint)"
      },
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "x-api-key: sk-... (Anthropic style; accepted by every endpoint except GET /v1/usage)"
      }
    }
  }
}
