> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aihubmax.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Mixed Understanding

> Use the returned task ID to [query the task](/pages/en/api-manual/task-management/get-task-detail) for the final result.



## OpenAPI

````yaml openapi/en/llm-custom.json POST /v1/llm/generations
openapi: 3.1.0
info:
  title: LLM · llm-custom protocol
  version: '1.0'
  description: >-
    Request format of the unified LLM entrypoint **`llm-custom`**: an OpenAI
    Chat Completions superset where the `messages[*].content` array accepts
    `video_url` / `audio_url` / `file_url` in addition to `text` / `image_url`;
    responses are uniformly returned as OpenAI `ChatCompletion` /
    `chat.completion.chunk`.


    **The `/v1/llm/generations` endpoint supports 5 request forms**:

    - `llm-text`: `prompt` only

    - `llm-vision`: `prompt` + `image_urls[]`

    - `llm-video`: `prompt` + `video_urls[]`

    - `llm-audio`: `audio_url`

    - `llm-custom` (this file): `messages[]` (OpenAI Chat compatible)


    The final task result is queried via `GET /v1/tasks/{task_id}`. The list of
    models available to the current token can be queried dynamically via `GET
    /v1/configs/llm_generations_models`.
servers:
  - url: https://api.aihubmax.com
security:
  - BearerAuth: []
paths:
  /v1/llm/generations:
    post:
      tags:
        - LLM > llm-custom
      summary: Submit an LLM generation task (llm-custom protocol)
      description: >-
        Use the returned task ID to [query the
        task](/pages/en/api-manual/task-management/get-task-detail) for the
        final result.
      operationId: llm-custom
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LLMCustomRequest'
            examples:
              openai_non_stream:
                summary: OpenAI Chat family · non-streaming
                value:
                  model: gpt-5.5
                  messages:
                    - role: user
                      content: count 1 to 3
                  stream: false
                  max_tokens: 32
              anthropic_stream:
                summary: Anthropic family · streaming (max_tokens required)
                value:
                  model: claude-opus-4-7
                  messages:
                    - role: system
                      content: You are a terse assistant.
                    - role: user
                      content: count 1 to 3
                  stream: true
                  max_tokens: 64
              gemini_stream:
                summary: Gemini family · streaming
                value:
                  model: gemini-3.5-flash
                  messages:
                    - role: user
                      content: count 1 to 3
                  stream: true
                  max_tokens: 64
              multimodal_image:
                summary: Multimodal · image_url (claude-opus-4-7)
                value:
                  model: claude-opus-4-7
                  messages:
                    - role: user
                      content:
                        - type: text
                          text: describe this image briefly
                        - type: image_url
                          image_url:
                            url: https://example.com/sample.png
                  stream: false
                  max_tokens: 256
      responses:
        '200':
          description: Task created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SubmitResponse'
              examples:
                non_stream:
                  summary: stream=false
                  value:
                    id: task-llm-1776874481-rj6bs3yb
                    object: llm.generation.task
                    type: llm
                    model: gpt-5.5
                    status: pending
                    progress: 0
                    created: 1776874481
                    stream: null
                    results: null
                    error: null
                stream:
                  summary: stream=true
                  value:
                    id: task-llm-1776874565-yq3szvcu
                    object: llm.generation.task
                    type: llm
                    model: claude-opus-4-7
                    status: pending
                    progress: 0
                    created: 1776874565
                    stream:
                      url: /v1/llm/generations/task-llm-1776874565-yq3szvcu/stream
                    results: null
                    error: null
        '401':
          $ref: '#/components/responses/Unauthorized'
        '422':
          $ref: '#/components/responses/UnprocessableEntity'
        '429':
          $ref: '#/components/responses/TooManyRequests'
        '500':
          $ref: '#/components/responses/InternalServerError'
        '503':
          $ref: '#/components/responses/ServiceUnavailable'
components:
  schemas:
    LLMCustomRequest:
      type: object
      required:
        - model
        - messages
      additionalProperties: true
      description: >-
        Request body in `messages[]` form (OpenAI Chat compatible). Apart from
        the fields listed below, other OpenAI-compatible parameters
        (`temperature`, `top_p`, `stop`, `frequency_penalty`, etc.) are used per
        the OpenAI Chat spec.
      properties:
        model:
          type: string
          description: >-
            [Get Model
            List](/pages/en/api-manual/text-series/llm-async/llm-generations-models)
          example: claude-opus-4-7
        messages:
          type: array
          description: >-
            OpenAI Chat format messages array. `messages[*].content` may be a
            string or an array; array element `type` ∈ {`text`, `image_url`,
            `video_url`, `audio_url`, `file_url`}. A `type` the model does not
            support returns 422 `model_not_support_capability`.


            **Typical content shapes:**


            1. Plain text (string content, simplest form):

            ```json

            [{"role": "user", "content": "count 1 to 3"}]

            ```


            2. Plain text (array content, the unified format when mixing with
            multimodal):

            ```json

            [{"role": "user", "content": [{"type": "text", "text": "count 1 to
            3"}]}]

            ```


            3. text + image:

            ```json

            [{"role": "user", "content": [
              {"type": "text", "text": "describe this image"},
              {"type": "image_url", "image_url": {"url": "https://example.com/x.png"}}
            ]}]

            ```


            4. text + video:

            ```json

            [{"role": "user", "content": [
              {"type": "text", "text": "summarize this video"},
              {"type": "video_url", "video_url": {"url": "https://example.com/clip.mp4"}}
            ]}]

            ```


            5. text + file:

            ```json

            [{"role": "user", "content": [
              {"type": "text", "text": "extract key points"},
              {"type": "file_url", "file_url": {"url": "https://example.com/doc.pdf"}}
            ]}]

            ```


            6. Multi-turn conversation (system + multiple user/assistant turns):

            ```json

            [
              {"role": "system", "content": "You are a terse assistant."},
              {"role": "user", "content": "1+1?"},
              {"role": "assistant", "content": "2"},
              {"role": "user", "content": "3+3?"}
            ]

            ```


            7. Mixed attachments of all types (a single user message containing
            2 each of `image_url` / `video_url` / `audio_url` / `file_url`):

            ```json

            [{"role": "user", "content": [
              {"type": "text", "text": "Summarize the key information from the following images, videos, audio, and documents"},
              {"type": "image_url", "image_url": {"url": "https://example.com/image-1.png"}},
              {"type": "image_url", "image_url": {"url": "https://example.com/image-2.jpg"}},
              {"type": "video_url", "video_url": {"url": "https://example.com/clip-1.mp4"}},
              {"type": "video_url", "video_url": {"url": "https://example.com/clip-2.mp4"}},
              {"type": "audio_url", "audio_url": {"url": "https://example.com/audio-1.mp3"}},
              {"type": "audio_url", "audio_url": {"url": "https://example.com/audio-2.wav"}},
              {"type": "file_url", "file_url": {"url": "https://example.com/doc-1.pdf"}},
              {"type": "file_url", "file_url": {"url": "https://example.com/doc-2.docx"}}
            ]}]

            ```


            **Inline base64 (asynchronous mode only, when `sync` is omitted or
            `false`)**: In `image_url` / `video_url` / `audio_url` / `file_url`
            blocks, inline base64 in the `{"url": ...}` object form (`data:`
            URI, or at least 4096 encoded characters whose decoded content
            matches a known media signature) is uploaded to file storage and
            replaced with a URL before the request is persisted or submitted
            upstream; the original base64 is not stored. Shorter raw base64 or
            content with an unrecognized signature is passed through unchanged
            and is not size-validated. Limits apply only to inline base64 items
            (public HTTP(S) URLs are not limited): decoded size ≤ 5 MB per item,
            ≤ 5 inline items per array, ≤ 10 MB total per request, and ≤ 20
            inline items per request. An invalid `data:` prefix or payload that
            decodes to zero bytes returns 422; exceeding a limit also returns
            422. Use `/v1/files/upload` first and pass the resulting URL
            instead.


            When `sync: true`, the request is not stored as a task and the rules
            above do not apply: inline base64 is submitted upstream unchanged
            without size or count validation.


            Shapes outside the coverage scope: `input_audio.data` /
            `file.file_data`, and the direct string form
            `{"type":"image_url","image_url":"data:..."}` (where the value is
            not a `{"url": ...}` object). Inline base64 in these shapes is
            passed through unchanged.
          items:
            $ref: '#/components/schemas/ChatMessage'
          example:
            - role: user
              content: count 1 to 3
        stream:
          type: boolean
          default: false
          description: >
            Whether to stream.


            **Behavior differences:**

            | Value | Submit response `stream` field | SSE endpoint |

            |---|---|---|

            | `false` | `null` | Not available |

            | `true` | `{"url": "/v1/llm/generations/{task_id}/stream"}` |
            Available; meanwhile task.data accumulates the full response |
          example: false
        max_tokens:
          type: integer
          nullable: true
          description: >-
            Generation token limit. Family-level constraints: `claude-*`
            **required**; `gpt-*` usually ≥ 16; `gemini-*` optional.
          example: 64
        temperature:
          type: number
          nullable: true
          description: Sampling temperature.
        top_p:
          type: number
          nullable: true
          description: Nucleus sampling.
        stop:
          description: Stop sequences.
          oneOf:
            - type: string
            - type: array
              items:
                type: string
    SubmitResponse:
      type: object
      description: >-
        Submit response, conforming to the unified task standard shape.
        `results` / `error` are fixed at `null` during submit; they are returned
        via `GET /v1/tasks/{task_id}` after the task completes or fails
      required:
        - id
        - object
        - type
        - model
        - status
        - progress
        - created
      properties:
        id:
          type: string
          description: >-
            Task ID, formatted as `task-llm-{timestamp}-{8random}`. Used for
            `GET /v1/tasks/{task_id}` queries or `GET
            /v1/llm/generations/{task_id}/stream` SSE subscriptions
          example: task-llm-1776874565-yq3szvcu
        object:
          type: string
          description: Object type, fixed at `llm.generation.task`
          enum:
            - llm.generation.task
          example: llm.generation.task
        type:
          type: string
          description: Media type, fixed at `llm`
          enum:
            - llm
          example: llm
        model:
          type: string
          description: The model name submitted by the client (echoed verbatim)
          example: claude-opus-4-7
        status:
          type: string
          description: Task status, fixed at `pending` during submit
          enum:
            - pending
          example: pending
        progress:
          type: integer
          description: Progress 0-100, fixed at 0 during submit
          example: 0
        created:
          type: integer
          description: Creation time (Unix seconds)
          example: 1776874565
        stream:
          nullable: true
          description: >-
            Returns `{url: ...}` when `stream=true`; `null` when `stream=false`.
            The client uses this to decide whether to connect to SSE
          oneOf:
            - $ref: '#/components/schemas/StreamInfo'
            - type: 'null'
        results:
          type: array
          nullable: true
          description: >-
            Fixed at `null` during submit; obtained via `GET
            /v1/tasks/{task_id}` after the task completes — `results[0]` is the
            full OpenAI `ChatCompletion` response.


            **Known limitation**: a thinking model's reasoning content
            (`reasoning_content`) appears only in the SSE stream's `delta` and
            is not accumulated into `results[0].message.content`
          items:
            type: object
          example: null
        error:
          type: object
          nullable: true
          description: >-
            Fixed at `null` during submit; returned via `GET
            /v1/tasks/{task_id}` when the task fails
          example: null
    ChatMessage:
      type: object
      required:
        - role
        - content
      properties:
        role:
          type: string
          enum:
            - system
            - user
            - assistant
          description: Message role (OpenAI naming)
        content:
          description: >-
            Message body. A string indicates plain text; an array indicates
            multimodal content blocks
          oneOf:
            - type: string
            - type: array
              items:
                $ref: '#/components/schemas/ContentBlock'
          example: count 1 to 3
    StreamInfo:
      type: object
      description: >-
        SSE subscription info. Returned as `SubmitResponse.stream` only when
        `stream=true`
      required:
        - url
      properties:
        url:
          type: string
          description: >-
            SSE subscription path, in the form
            `/v1/llm/generations/{task_id}/stream`
          example: /v1/llm/generations/task-llm-1776874565-yq3szvcu/stream
    ErrorResponse401:
      type: object
      properties:
        error:
          type: object
          properties:
            message:
              type: string
              example: No authentication token provided
            type:
              type: string
              example: authentication_error
    ErrorResponse422:
      type: object
      description: >-
        Parameter validation failure. Common `code`s:

        - `no_available_model`: the requested model is currently not configured
        or unavailable

        - `model_not_support_capability`: the requested content type combination
        (e.g. text + video) is not supported by this model

        - `model_rule_violation`: a model rule was violated; the specific
        sub-rule name appears in the error body `code` field (e.g.
        `gemini_video_size_exceeded`, `anthropic_max_tokens_required`)

        - `invalid_param`: a regular schema validation failure (including
        `max_tokens` family constraint violations, etc.)
      properties:
        error:
          type: object
          properties:
            message:
              type: string
              example: >-
                Model gpt-5.5 does not support using text + video together;
                please switch models or contact the administrator.
            type:
              type: string
              example: invalid_request_error
            code:
              type: string
              example: model_not_support_capability
    ErrorResponse429:
      type: object
      properties:
        error:
          type: object
          properties:
            message:
              type: string
              example: Request rate limit exceeded
            type:
              type: string
              example: rate_limit_error
    ErrorResponse500:
      type: object
      properties:
        error:
          type: object
          properties:
            message:
              type: string
              example: Internal server error
            type:
              type: string
              example: internal_error
    ErrorResponse503:
      type: object
      properties:
        error:
          type: object
          properties:
            message:
              type: string
              example: Upstream temporarily unavailable
            type:
              type: string
              example: service_unavailable
    ContentBlock:
      type: object
      description: >-
        Multimodal content block. Different `type`s use different parallel
        fields to carry the URL or text
      required:
        - type
      properties:
        type:
          type: string
          enum:
            - text
            - image_url
            - video_url
            - audio_url
            - file_url
          description: Content block type
        text:
          type: string
          description: Required when `type=text`
        image_url:
          type: object
          description: Required when `type=image_url`
          required:
            - url
          properties:
            url:
              type: string
              description: Publicly accessible image URL (or base64 data URL)
        video_url:
          type: object
          description: >-
            Required when `type=video_url`; returns 422
            `model_not_support_capability` if the model does not support it
          required:
            - url
          properties:
            url:
              type: string
        audio_url:
          type: object
          description: >-
            Required when `type=audio_url`; returns 422
            `model_not_support_capability` if the model does not support it
          required:
            - url
          properties:
            url:
              type: string
        file_url:
          type: object
          description: >-
            Required when `type=file_url`; returns 422
            `model_not_support_capability` if the model does not support it
          required:
            - url
          properties:
            url:
              type: string
  responses:
    Unauthorized:
      description: Token invalid or missing
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse401'
    UnprocessableEntity:
      description: >-
        Parameter validation failure, or the model does not support this
        request; see the response body `error.code` for the specific reason
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse422'
    TooManyRequests:
      description: Request rate limit exceeded
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse429'
    InternalServerError:
      description: Internal server error
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse500'
    ServiceUnavailable:
      description: Upstream is unavailable
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse503'
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
      description: >-
        All endpoints require Bearer Token authentication. Add to the request
        header:


        `Authorization: Bearer YOUR_API_KEY`


        `YOUR_API_KEY` is the API Token (`sk-...` format).

````