{
  "openapi": "3.1.0",
  "info": {
    "title": "ModelMesh API",
    "version": "1.0.0",
    "description": "OpenAI-compatible API of the ModelMesh AI aggregator. In your OpenAI SDK, change only `base_url` to `https://api.modelmesh.shop/v1` and the key to `mm_live_...` — and everything works (Cursor, LangChain, n8n, OpenAI SDK). The cost of each request is returned in `usage.cost_mt` (Mesh tokens) and in the `X-ModelMesh-Cost` header. Images, speech synthesis and speech recognition use the OpenAI-compatible `/images/*` and `/audio/*`; video, music and any long-running generations use asynchronous `/tasks` with a notification to `webhook_url`.",
    "contact": {
      "name": "ModelMesh",
      "url": "https://modelmesh.shop"
    }
  },
  "servers": [
    {
      "url": "https://api.modelmesh.shop/v1",
      "description": "Production"
    }
  ],
  "security": [
    {
      "ApiKeyAuth": []
    }
  ],
  "tags": [
    {
      "name": "Models"
    },
    {
      "name": "Chat"
    },
    {
      "name": "Embeddings"
    },
    {
      "name": "Account"
    },
    {
      "name": "Images"
    },
    {
      "name": "Audio"
    },
    {
      "name": "Tasks"
    }
  ],
  "paths": {
    "/models": {
      "get": {
        "tags": [
          "Models"
        ],
        "summary": "List of models",
        "description": "Models available to your key, with prices in Mesh tokens (MT).",
        "responses": {
          "200": {
            "description": "List of models",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModelList"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "operationId": "listModels"
      }
    },
    "/chat/completions": {
      "post": {
        "tags": [
          "Chat"
        ],
        "summary": "Chat (OpenAI chat.completions)",
        "description": "Supports `stream: true` (SSE in the OpenAI format), `tools` (function calling) and vision (images in `content`). Charges are taken from the prepaid key's wallet or from the account balance within the key's limit. Test keys `mm_test_` return a stub without charges. Only `n=1` is supported. When streaming, the price arrives in the last `usage` chunk (`cost_mt`); the `X-ModelMesh-Balance` header is the balance before the request.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ChatCompletionRequest"
              },
              "examples": {
                "simple": {
                  "summary": "Simple request",
                  "value": {
                    "model": "gpt-5.6-luna",
                    "messages": [
                      {
                        "role": "user",
                        "content": "Hi! Who are you?"
                      }
                    ]
                  }
                },
                "stream": {
                  "summary": "Stream",
                  "value": {
                    "model": "gpt-5.6-luna",
                    "stream": true,
                    "messages": [
                      {
                        "role": "user",
                        "content": "Write a haiku about tokens"
                      }
                    ]
                  }
                },
                "vision": {
                  "summary": "Vision",
                  "value": {
                    "model": "gpt-5.6-luna",
                    "messages": [
                      {
                        "role": "user",
                        "content": [
                          {
                            "type": "text",
                            "text": "What is in the picture?"
                          },
                          {
                            "type": "image_url",
                            "image_url": {
                              "url": "https://example.com/cat.png"
                            }
                          }
                        ]
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The model's response. With `stream: true` — `text/event-stream` (`data: {...}` chunks + `data: [DONE]`).",
            "headers": {
              "X-ModelMesh-Cost": {
                "$ref": "#/components/headers/XModelMeshCost"
              },
              "X-ModelMesh-Balance": {
                "$ref": "#/components/headers/XModelMeshBalance"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChatCompletion"
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientBalance"
          },
          "403": {
            "$ref": "#/components/responses/ModelNotAllowed"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/ModelNotFound"
          },
          "502": {
            "$ref": "#/components/responses/ProviderError"
          }
        },
        "operationId": "createChatCompletion"
      }
    },
    "/embeddings": {
      "post": {
        "tags": [
          "Embeddings"
        ],
        "summary": "Embeddings (OpenAI embeddings)",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EmbeddingsRequest"
              },
              "examples": {
                "simple": {
                  "value": {
                    "model": "text-embedding-3-small",
                    "input": "Text to search for"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Embeddings",
            "headers": {
              "X-ModelMesh-Cost": {
                "$ref": "#/components/headers/XModelMeshCost"
              },
              "X-ModelMesh-Balance": {
                "$ref": "#/components/headers/XModelMeshBalance"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EmbeddingList"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientBalance"
          },
          "403": {
            "$ref": "#/components/responses/ModelNotAllowed"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/ModelNotFound"
          },
          "502": {
            "$ref": "#/components/responses/ProviderError"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        },
        "operationId": "createEmbedding"
      }
    },
    "/balance": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "Key balance",
        "description": "For a prepaid key — the key's wallet balance; for a limit key — the minimum of the remaining limit and the account balance.",
        "responses": {
          "200": {
            "description": "Balance",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Balance"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        },
        "operationId": "getBalance"
      }
    },
    "/usage": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "Key usage",
        "parameters": [
          {
            "name": "from",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          },
          {
            "name": "to",
            "in": "query",
            "schema": {
              "type": "string",
              "format": "date-time"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Usage by day",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageReport"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          }
        },
        "operationId": "getUsage"
      }
    },
    "/images/generations": {
      "post": {
        "tags": [
          "Images"
        ],
        "operationId": "createImage",
        "summary": "Image generation (OpenAI images)",
        "description": "Models of the `image` category from `GET /models`. `size` is converted to the model's aspect ratio and resolution, `n` is the number of images (if the model supports it), other model parameters go in `extra` (the `ui_schema` keys from `GET /models`). The response arrives when the image is ready; `url` links are signed and valid for one day. Only the price of images actually received is charged; on a provider error nothing is charged (`usage.cost_mt`).",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Retrying a request with the same key does not start a second generation and does not charge twice.",
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImageGenerationRequest"
              },
              "examples": {
                "simple": {
                  "value": {
                    "model": "nano-banana-2",
                    "prompt": "Astronaut cat, watercolor",
                    "size": "1792x1024",
                    "n": 1
                  }
                }
              }
            }
          }
        },
        "responses": {
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientBalance"
          },
          "403": {
            "$ref": "#/components/responses/ModelNotAllowed"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/ModelNotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "200": {
            "description": "Images",
            "headers": {
              "X-ModelMesh-Cost": {
                "$ref": "#/components/headers/XModelMeshCost"
              },
              "X-ModelMesh-Balance": {
                "$ref": "#/components/headers/XModelMeshBalance"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImagesResponse"
                }
              }
            }
          },
          "202": {
            "description": "The generation did not finish within 5 minutes: `data` is empty, the task is in `modelmesh_task`, and the result is available via `GET /tasks/{id}` (a retry with the same Idempotency-Key waits for the same generation).",
            "headers": {
              "X-ModelMesh-Task-Id": {
                "description": "Task id",
                "schema": {
                  "type": "string",
                  "format": "uuid"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PendingResult"
                }
              }
            }
          },
          "502": {
            "$ref": "#/components/responses/ProviderError"
          }
        }
      }
    },
    "/images/edits": {
      "post": {
        "tags": [
          "Images"
        ],
        "operationId": "editImage",
        "summary": "Image editing (OpenAI images/edits)",
        "description": "`multipart/form-data`: `image` (one or more PNG/JPEG/WebP/GIF files), `prompt`, `model`, `n`, `size`, `response_format`. Or JSON with data-URL images: `images: [{ \"image_url\": \"data:image/png;base64,...\" }]`. External URLs are not accepted, `mask` is not supported. Models are of the `image` category with an image field in `ui_schema`.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Retrying a request with the same key does not start a second generation and does not charge twice.",
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/ImageEditForm"
              }
            },
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ImageEditJson"
              }
            }
          }
        },
        "responses": {
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientBalance"
          },
          "403": {
            "$ref": "#/components/responses/ModelNotAllowed"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/ModelNotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "200": {
            "description": "Images",
            "headers": {
              "X-ModelMesh-Cost": {
                "$ref": "#/components/headers/XModelMeshCost"
              },
              "X-ModelMesh-Balance": {
                "$ref": "#/components/headers/XModelMeshBalance"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ImagesResponse"
                }
              }
            }
          },
          "202": {
            "description": "The generation did not finish within 5 minutes: `data` is empty, the task is in `modelmesh_task`, and the result is available via `GET /tasks/{id}` (a retry with the same Idempotency-Key waits for the same generation).",
            "headers": {
              "X-ModelMesh-Task-Id": {
                "description": "Task id",
                "schema": {
                  "type": "string",
                  "format": "uuid"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PendingResult"
                }
              }
            }
          },
          "502": {
            "$ref": "#/components/responses/ProviderError"
          }
        }
      }
    },
    "/audio/speech": {
      "post": {
        "tags": [
          "Audio"
        ],
        "operationId": "createSpeech",
        "summary": "Text to speech (OpenAI audio/speech)",
        "description": "The response is an audio file (`audio/*`). `voice` is a model voice from `ui_schema` (standard OpenAI voices are replaced with the model's default voice). The price is per character count.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Retrying a request with the same key does not start a second generation and does not charge twice.",
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SpeechRequest"
              },
              "examples": {
                "simple": {
                  "value": {
                    "model": "elevenlabs-v4",
                    "input": "Hello! This is ModelMesh.",
                    "voice": "Sarah"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientBalance"
          },
          "403": {
            "$ref": "#/components/responses/ModelNotAllowed"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/ModelNotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "200": {
            "description": "Audio",
            "headers": {
              "X-ModelMesh-Cost": {
                "$ref": "#/components/headers/XModelMeshCost"
              },
              "X-ModelMesh-Balance": {
                "$ref": "#/components/headers/XModelMeshBalance"
              }
            },
            "content": {
              "audio/mpeg": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              },
              "audio/wav": {
                "schema": {
                  "type": "string",
                  "format": "binary"
                }
              }
            }
          },
          "202": {
            "description": "The generation did not finish within 5 minutes: `data` is empty, the task is in `modelmesh_task`, and the result is available via `GET /tasks/{id}` (a retry with the same Idempotency-Key waits for the same generation).",
            "headers": {
              "X-ModelMesh-Task-Id": {
                "description": "Task id",
                "schema": {
                  "type": "string",
                  "format": "uuid"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PendingResult"
                }
              }
            }
          },
          "502": {
            "$ref": "#/components/responses/ProviderError"
          }
        }
      }
    },
    "/audio/transcriptions": {
      "post": {
        "tags": [
          "Audio"
        ],
        "operationId": "createTranscription",
        "summary": "Speech recognition (OpenAI audio/transcriptions)",
        "description": "`multipart/form-data`: `file` (MP3, WAV, M4A, OGG, MP4, MOV), `model`, `language`, `response_format` (`json`, `text`, `verbose_json`). The price is per duration, measured from the file.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Retrying a request with the same key does not start a second generation and does not charge twice.",
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "$ref": "#/components/schemas/TranscriptionForm"
              }
            }
          }
        },
        "responses": {
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientBalance"
          },
          "403": {
            "$ref": "#/components/responses/ModelNotAllowed"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/ModelNotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "200": {
            "description": "Text",
            "headers": {
              "X-ModelMesh-Cost": {
                "$ref": "#/components/headers/XModelMeshCost"
              },
              "X-ModelMesh-Balance": {
                "$ref": "#/components/headers/XModelMeshBalance"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Transcription"
                }
              },
              "text/plain": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "202": {
            "description": "The generation did not finish within 5 minutes: `data` is empty, the task is in `modelmesh_task`, and the result is available via `GET /tasks/{id}` (a retry with the same Idempotency-Key waits for the same generation).",
            "headers": {
              "X-ModelMesh-Task-Id": {
                "description": "Task id",
                "schema": {
                  "type": "string",
                  "format": "uuid"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PendingResult"
                }
              }
            }
          },
          "502": {
            "$ref": "#/components/responses/ProviderError"
          }
        }
      }
    },
    "/tasks": {
      "post": {
        "tags": [
          "Tasks"
        ],
        "operationId": "createTask",
        "summary": "Asynchronous task: video, music, any media model",
        "description": "Responds immediately with `202` and a task (`status: queued`). Tokens are reserved at the price when the task starts and charged only for a finished result; on an error or timeout (2 h) they are returned. You can learn about completion by polling `GET /tasks/{id}` or via `webhook_url` (https): ModelMesh sends a POST with the event `task.succeeded`, `task.failed` or `task.canceled` and the signature `X-ModelMesh-Signature: t=<unix>,v1=<hex>` — HMAC-SHA256 of `<t>.<body>` with the secret from `GET /webhooks/secret`. A failed delivery (non-2xx) is retried with a delay for up to ~a day; discard duplicates by the `webhook-id` header.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "description": "Retrying a request with the same key does not start a second generation and does not charge twice.",
            "schema": {
              "type": "string",
              "maxLength": 200
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/TaskRequest"
              },
              "examples": {
                "video": {
                  "value": {
                    "model": "kling-3-pro",
                    "input": {
                      "prompt": "Lighthouse in a storm, camera circling",
                      "durationSec": 5
                    },
                    "webhook_url": "https://example.com/modelmesh/webhook"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/InsufficientBalance"
          },
          "403": {
            "$ref": "#/components/responses/ModelNotAllowed"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "404": {
            "$ref": "#/components/responses/ModelNotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          },
          "202": {
            "description": "Task created",
            "headers": {
              "X-ModelMesh-Task-Id": {
                "description": "Task id",
                "schema": {
                  "type": "string",
                  "format": "uuid"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Task"
                }
              }
            }
          },
          "409": {
            "description": "The Idempotency-Key has already been used by another request.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/tasks/{id}": {
      "get": {
        "tags": [
          "Tasks"
        ],
        "operationId": "getTask",
        "summary": "Task status and result",
        "description": "Only tasks and synchronous generations created by this key are visible. File links are signed and valid for one day — request the task again to get fresh ones.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Task",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Task"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "description": "Task not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/webhooks/secret": {
      "get": {
        "tags": [
          "Tasks"
        ],
        "operationId": "getWebhookSecret",
        "summary": "Webhook signature verification secret",
        "description": "The `whsec_...` secret for verifying `X-ModelMesh-Signature` on this key's task events.",
        "responses": {
          "200": {
            "description": "Secret",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/WebhookSecret"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "ApiKeyAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "`Authorization: Bearer mm_live_...`. Test keys are `mm_test_...` (no charges)."
      }
    },
    "headers": {
      "XModelMeshCost": {
        "description": "Mesh tokens (MT) charged for the request.",
        "schema": {
          "type": "string"
        }
      },
      "XModelMeshBalance": {
        "description": "Mesh tokens (MT) remaining after the request.",
        "schema": {
          "type": "string"
        }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "The key is missing, invalid, suspended, revoked or expired.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "InsufficientBalance": {
        "description": "Insufficient tokens (account/key balance or the key's limit is exhausted).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "ModelNotAllowed": {
        "description": "This model or category is not allowed for the key.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "RateLimited": {
        "description": "The key's rpm limit has been exceeded.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "BadRequest": {
        "description": "Invalid request (invalid_request, content_policy_violation, n>1 is not supported).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "ModelNotFound": {
        "description": "The model was not found or is unavailable (model_not_found).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      },
      "ProviderError": {
        "description": "The model provider is temporarily unavailable (provider_error).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            }
          }
        }
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "message": {
                "type": "string"
              },
              "type": {
                "type": "string"
              },
              "param": {
                "type": [
                  "string",
                  "null"
                ]
              },
              "code": {
                "type": "string"
              }
            },
            "required": [
              "message",
              "type",
              "code"
            ]
          }
        }
      },
      "ChatMessage": {
        "type": "object",
        "properties": {
          "role": {
            "type": "string",
            "enum": [
              "system",
              "developer",
              "user",
              "assistant",
              "tool"
            ]
          },
          "content": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ContentPart"
                }
              }
            ]
          },
          "name": {
            "type": "string"
          },
          "tool_calls": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ToolCall"
            }
          },
          "tool_call_id": {
            "type": "string"
          }
        },
        "required": [
          "role"
        ]
      },
      "ContentPart": {
        "oneOf": [
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "text"
              },
              "text": {
                "type": "string"
              }
            },
            "required": [
              "type",
              "text"
            ]
          },
          {
            "type": "object",
            "properties": {
              "type": {
                "const": "image_url"
              },
              "image_url": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string"
                  },
                  "detail": {
                    "type": "string",
                    "enum": [
                      "auto",
                      "low",
                      "high"
                    ]
                  }
                },
                "required": [
                  "url"
                ]
              }
            },
            "required": [
              "type",
              "image_url"
            ]
          }
        ]
      },
      "ToolCall": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "type": {
            "const": "function"
          },
          "function": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "arguments": {
                "type": "string"
              }
            },
            "required": [
              "name",
              "arguments"
            ]
          }
        },
        "required": [
          "id",
          "type",
          "function"
        ]
      },
      "Tool": {
        "type": "object",
        "properties": {
          "type": {
            "const": "function"
          },
          "function": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "description": {
                "type": "string"
              },
              "parameters": {
                "type": "object"
              }
            },
            "required": [
              "name"
            ]
          }
        },
        "required": [
          "type",
          "function"
        ]
      },
      "ChatCompletionRequest": {
        "type": "object",
        "properties": {
          "model": {
            "type": "string"
          },
          "messages": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ChatMessage"
            }
          },
          "stream": {
            "type": "boolean",
            "default": false
          },
          "max_tokens": {
            "type": "integer"
          },
          "max_completion_tokens": {
            "type": "integer"
          },
          "temperature": {
            "type": "number"
          },
          "top_p": {
            "type": "number"
          },
          "n": {
            "type": "integer"
          },
          "stop": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ]
          },
          "seed": {
            "type": "integer"
          },
          "tools": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Tool"
            }
          },
          "tool_choice": {},
          "response_format": {
            "type": "object"
          },
          "user": {
            "type": "string"
          }
        },
        "required": [
          "model",
          "messages"
        ]
      },
      "Usage": {
        "type": "object",
        "properties": {
          "prompt_tokens": {
            "type": "integer"
          },
          "completion_tokens": {
            "type": "integer"
          },
          "total_tokens": {
            "type": "integer"
          },
          "cost_mt": {
            "type": "string",
            "description": "Mesh tokens (MT) charged, as a decimal string."
          },
          "cost_mmt": {
            "type": "string",
            "description": "The same in milli-tokens (integer)."
          }
        }
      },
      "ChatCompletion": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "const": "chat.completion"
          },
          "created": {
            "type": "integer"
          },
          "model": {
            "type": "string"
          },
          "choices": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "index": {
                  "type": "integer"
                },
                "message": {
                  "$ref": "#/components/schemas/ChatMessage"
                },
                "finish_reason": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              }
            }
          },
          "usage": {
            "$ref": "#/components/schemas/Usage"
          }
        }
      },
      "EmbeddingsRequest": {
        "type": "object",
        "properties": {
          "model": {
            "type": "string"
          },
          "input": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "type": "string"
                }
              }
            ]
          },
          "dimensions": {
            "type": "integer"
          },
          "user": {
            "type": "string"
          }
        },
        "required": [
          "model",
          "input"
        ]
      },
      "EmbeddingList": {
        "type": "object",
        "properties": {
          "object": {
            "const": "list"
          },
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "object": {
                  "const": "embedding"
                },
                "index": {
                  "type": "integer"
                },
                "embedding": {
                  "type": "array",
                  "items": {
                    "type": "number"
                  }
                }
              }
            }
          },
          "model": {
            "type": "string"
          },
          "usage": {
            "$ref": "#/components/schemas/Usage"
          }
        }
      },
      "ModelList": {
        "type": "object",
        "properties": {
          "object": {
            "const": "list"
          },
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "object": {
                  "const": "model"
                },
                "owned_by": {
                  "type": "string"
                },
                "category": {
                  "type": "string"
                },
                "context_window": {
                  "type": [
                    "integer",
                    "null"
                  ]
                },
                "operation": {
                  "type": "string",
                  "enum": [
                    "image",
                    "video",
                    "music",
                    "speech",
                    "transcription"
                  ],
                  "description": "Media models only: which method to use (`/images/*`, `/audio/*`, `/tasks`)."
                },
                "ui_schema": {
                  "type": "object",
                  "description": "Media models only: parameter fields (`fields[].key`, type, options, default) — for `extra` and the task `input`."
                }
              }
            }
          }
        }
      },
      "Balance": {
        "type": "object",
        "properties": {
          "object": {
            "const": "balance"
          },
          "mode": {
            "type": "string",
            "enum": [
              "limit",
              "prepaid"
            ]
          },
          "balance_mt": {
            "type": "string"
          },
          "balance_mmt": {
            "type": "string"
          },
          "currency": {
            "const": "MT"
          }
        }
      },
      "UsageReport": {
        "type": "object",
        "properties": {
          "object": {
            "const": "usage"
          },
          "from": {
            "type": "string",
            "format": "date-time"
          },
          "to": {
            "type": "string",
            "format": "date-time"
          },
          "total_cost_mt": {
            "type": "string"
          },
          "total_cost_mmt": {
            "type": "string"
          },
          "total_requests": {
            "type": "integer"
          },
          "days": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "date": {
                  "type": "string",
                  "description": "YYYY-MM-DD (UTC)"
                },
                "cost_mt": {
                  "type": "string"
                },
                "cost_mmt": {
                  "type": "string"
                },
                "requests": {
                  "type": "integer"
                }
              }
            }
          }
        }
      },
      "ImageGenerationRequest": {
        "type": "object",
        "required": [
          "model",
          "prompt"
        ],
        "properties": {
          "model": {
            "type": "string"
          },
          "prompt": {
            "type": "string",
            "maxLength": 5000
          },
          "n": {
            "type": "integer",
            "minimum": 1,
            "maximum": 10
          },
          "size": {
            "type": "string",
            "example": "1024x1024",
            "description": "WxH or auto"
          },
          "quality": {
            "type": "string",
            "description": "standard | hd | low | medium | high | auto — if the model supports it"
          },
          "style": {
            "type": "string"
          },
          "response_format": {
            "type": "string",
            "enum": [
              "url",
              "b64_json"
            ],
            "default": "url"
          },
          "extra": {
            "type": "object",
            "additionalProperties": {
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "number"
                },
                {
                  "type": "boolean"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            },
            "description": "Model parameters — the `ui_schema` keys from GET /models."
          }
        }
      },
      "ImageEditForm": {
        "type": "object",
        "required": [
          "model",
          "prompt",
          "image"
        ],
        "properties": {
          "model": {
            "type": "string"
          },
          "prompt": {
            "type": "string"
          },
          "image": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "binary"
            }
          },
          "n": {
            "type": "integer"
          },
          "size": {
            "type": "string"
          },
          "response_format": {
            "type": "string",
            "enum": [
              "url",
              "b64_json"
            ]
          },
          "extra": {
            "type": "string",
            "description": "JSON object of model parameters"
          }
        }
      },
      "ImageEditJson": {
        "allOf": [
          {
            "$ref": "#/components/schemas/ImageGenerationRequest"
          },
          {
            "type": "object",
            "properties": {
              "images": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "image_url": {
                      "type": "string",
                      "description": "data:image/...;base64,..."
                    }
                  }
                }
              }
            }
          }
        ]
      },
      "ImagesResponse": {
        "type": "object",
        "properties": {
          "created": {
            "type": "integer"
          },
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "url": {
                  "type": "string"
                },
                "b64_json": {
                  "type": "string"
                }
              }
            }
          },
          "usage": {
            "type": "object",
            "properties": {
              "cost_mt": {
                "type": "string",
                "description": "Charged, MT (decimal string)"
              },
              "cost_mmt": {
                "type": "string",
                "description": "Charged, mMT"
              }
            }
          }
        }
      },
      "PendingResult": {
        "type": "object",
        "properties": {
          "created": {
            "type": "integer"
          },
          "data": {
            "type": "array",
            "maxItems": 0,
            "items": {}
          },
          "modelmesh_task": {
            "$ref": "#/components/schemas/Task"
          }
        }
      },
      "SpeechRequest": {
        "type": "object",
        "required": [
          "model",
          "input"
        ],
        "properties": {
          "model": {
            "type": "string"
          },
          "input": {
            "type": "string",
            "maxLength": 5000
          },
          "voice": {
            "type": "string"
          },
          "response_format": {
            "type": "string"
          },
          "speed": {
            "type": "number"
          },
          "extra": {
            "type": "object",
            "additionalProperties": {
              "oneOf": [
                {
                  "type": "string"
                },
                {
                  "type": "number"
                },
                {
                  "type": "boolean"
                },
                {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                }
              ]
            },
            "description": "Model parameters — the `ui_schema` keys from GET /models."
          }
        }
      },
      "TranscriptionForm": {
        "type": "object",
        "required": [
          "model",
          "file"
        ],
        "properties": {
          "model": {
            "type": "string"
          },
          "file": {
            "type": "string",
            "format": "binary"
          },
          "language": {
            "type": "string"
          },
          "response_format": {
            "type": "string",
            "enum": [
              "json",
              "text",
              "verbose_json"
            ]
          },
          "extra": {
            "type": "string",
            "description": "JSON object of model parameters"
          }
        }
      },
      "Transcription": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string"
          },
          "language": {
            "type": [
              "string",
              "null"
            ]
          },
          "duration": {
            "type": [
              "number",
              "null"
            ]
          },
          "usage": {
            "type": "object",
            "properties": {
              "cost_mt": {
                "type": "string",
                "description": "Charged, MT (decimal string)"
              },
              "cost_mmt": {
                "type": "string",
                "description": "Charged, mMT"
              }
            }
          }
        }
      },
      "TaskRequest": {
        "type": "object",
        "required": [
          "model"
        ],
        "properties": {
          "model": {
            "type": "string"
          },
          "input": {
            "type": "object",
            "description": "`prompt` and model parameters (`ui_schema` keys from GET /models). Input files (reference image, audio) are data-URLs.",
            "additionalProperties": true
          },
          "webhook_url": {
            "type": "string",
            "format": "uri",
            "description": "https URL for the completion event"
          }
        }
      },
      "TaskFile": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "kind": {
            "type": "string",
            "enum": [
              "image",
              "video",
              "audio",
              "document"
            ]
          },
          "mime": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "description": "Signed link"
          },
          "url_expires_at": {
            "type": "integer"
          },
          "size_bytes": {
            "type": [
              "integer",
              "null"
            ]
          },
          "width": {
            "type": [
              "integer",
              "null"
            ]
          },
          "height": {
            "type": [
              "integer",
              "null"
            ]
          },
          "duration_ms": {
            "type": [
              "integer",
              "null"
            ]
          }
        }
      },
      "Task": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "object": {
            "type": "string",
            "const": "task"
          },
          "model": {
            "type": "string"
          },
          "category": {
            "type": "string"
          },
          "operation": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "queued",
              "in_progress",
              "succeeded",
              "failed",
              "canceled"
            ]
          },
          "progress": {
            "type": [
              "integer",
              "null"
            ]
          },
          "created_at": {
            "type": "integer"
          },
          "finished_at": {
            "type": [
              "integer",
              "null"
            ]
          },
          "price_mt": {
            "type": "string",
            "description": "Price at start (reserved), MT"
          },
          "price_mmt": {
            "type": "string"
          },
          "cost_mt": {
            "type": "string",
            "description": "Charged, MT (decimal string)"
          },
          "cost_mmt": {
            "type": "string",
            "description": "Charged, mMT"
          },
          "output": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "files": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/TaskFile"
                }
              },
              "text": {
                "type": [
                  "string",
                  "null"
                ]
              }
            }
          },
          "error": {
            "type": [
              "object",
              "null"
            ],
            "properties": {
              "code": {
                "type": "string"
              },
              "message": {
                "type": "string"
              }
            }
          },
          "webhook_url": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "WebhookSecret": {
        "type": "object",
        "properties": {
          "object": {
            "type": "string",
            "const": "webhook_secret"
          },
          "secret": {
            "type": "string",
            "example": "whsec_..."
          },
          "signature_header": {
            "type": "string"
          },
          "algorithm": {
            "type": "string"
          }
        }
      }
    }
  }
}
