{
  "openapi": "3.1.0",
  "info": {
    "title": "Apimodelhub API",
    "version": "1.0.0",
    "description": "Một endpoint, một key, cho Claude, GPT, Grok, Gemini và DeepSeek.\n\nMọi model đều được tính bằng **một tỷ giá duy nhất**: bạn trả **$0.115 cho mỗi $1 giá gốc**\ncủa nhà cung cấp (1 credit-$ = 3,250 ₫). Giá theo\n1 triệu token, trừ từ credit trả trước — không thuê bao.\n\nBa giao thức, cùng một key: Anthropic Messages (`/v1/messages`), OpenAI\nChat Completions/Responses (`/v1/chat/completions`, `/v1/responses`) và Gemini\n`generateContent` (`/v1beta/models/{model}:generateContent`). Stream được chuyển\nnguyên văn (byte-exact), không buffer.\n\n**Giao thức phải khớp họ model.** Gateway chuyển path nguyên văn lên nhà cung cấp\ncủa model, không dịch giữa các giao thức: model `claude-*` chỉ gọi được qua\n`/v1/messages`; `gpt-*` và `grok-*` và `deepseek-*` qua `/v1/chat/completions` hoặc\n`/v1/responses`; `gemini-*` qua `/v1beta/models/...`. Gọi sai đường thì nhà cung cấp\ntrả 404 của chính họ (không phải lỗi key).\n\nMã lỗi dùng chung một hình dạng `{\"type\":\"error\",\"error\":{\"type\",\"message\"}}`.\nGiới hạn: 600 request/phút mỗi key (trả 429 kèm `retry-after`), tối đa 500 request\nđồng thời mỗi key, và hạn mức trả trước (402 khi không đủ cho chi phí xấu nhất).",
    "license": {
      "name": "Proprietary"
    }
  },
  "servers": [
    {
      "url": "https://api.apimodelhub.com",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearer": []
    }
  ],
  "tags": [
    {
      "name": "Models",
      "description": "Model đang bán và giá hiện tại."
    },
    {
      "name": "Anthropic",
      "description": "Anthropic Messages API — dùng bởi Anthropic SDK và Claude Code."
    },
    {
      "name": "OpenAI",
      "description": "OpenAI Chat Completions và Responses API — dùng bởi OpenAI SDK."
    },
    {
      "name": "Google",
      "description": "Gemini generateContent — dùng bởi google-genai SDK."
    }
  ],
  "components": {
    "securitySchemes": {
      "bearer": {
        "type": "http",
        "scheme": "bearer",
        "description": "`Authorization: Bearer sk-spk-…` — dùng cho SDK OpenAI và mọi client HTTP thông thường."
      },
      "anthropicKey": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "`x-api-key: sk-spk-…` — kiểu Anthropic SDK / Claude Code. Cùng một key, khác cách gửi."
      }
    },
    "schemas": {
      "Usage": {
        "type": "object",
        "description": "Số token thực tế của lượt gọi. Cache read/write được trả riêng vì giá khác hẳn giá input — gộp lại thì không đối soát được hoá đơn.",
        "properties": {
          "input_tokens": {
            "type": "integer",
            "description": "Token input KHÔNG tính phần cache read."
          },
          "output_tokens": {
            "type": "integer"
          },
          "cache_read_input_tokens": {
            "type": "integer",
            "description": "Token đọc từ prompt cache."
          },
          "cache_creation_input_tokens": {
            "type": "integer",
            "description": "Token ghi vào cache (5m + 1h)."
          }
        }
      },
      "Pricing": {
        "type": "object",
        "description": "Giá BÁN của chúng tôi, tính bằng **credit-$** trên 1 triệu token (1 credit-$ = 3,250 ₫, xem `credit_vnd_per_usd`). Không phải USD thật: tên field `pricing_usd_per_1m` được giữ để client cũ không vỡ.",
        "properties": {
          "input": {
            "type": "number",
            "description": "Giá input — số bạn thực trả."
          },
          "output": {
            "type": "number"
          },
          "cache_read": {
            "type": [
              "number",
              "null"
            ],
            "description": "Giá đọc cache; null nếu model không hỗ trợ."
          },
          "cache_write_5m": {
            "type": [
              "number",
              "null"
            ],
            "description": "Giá ghi cache TTL 5 phút. Bằng đúng `input` nghĩa là hãng không phụ phí ghi cache (xAI, Google, DeepSeek, OpenAI ≤ 5.5); Anthropic và OpenAI từ 5.6 tính 1.25× input. null chỉ khi dòng giá chưa khai mức này."
          },
          "cache_write_1h": {
            "type": [
              "number",
              "null"
            ],
            "description": "Giá ghi cache TTL dài (1 giờ ở Anthropic, 12 giờ ở OpenAI từ 5.6). Bằng đúng `input` nghĩa là hãng không phụ phí ghi cache."
          }
        }
      },
      "Error": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "description": "`error` — cùng hình dạng với Anthropic và OpenAI."
          },
          "error": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "description": "authentication_error | invalid_request_error | not_found_error | rate_limit_error | permission_error"
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      }
    },
    "responses": {
      "Unauthorized": {
        "description": "Key thiếu, sai, hoặc đã bị thu hồi.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "type": "error",
              "error": {
                "type": "authentication_error",
                "message": "invalid api key"
              }
            }
          }
        }
      },
      "BadRequest": {
        "description": "Request không hợp lệ: body không phải JSON (400), thiếu `model` (400), hoặc body vượt 32 MB (413).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "type": "error",
              "error": {
                "type": "invalid_request_error",
                "message": "missing model"
              }
            }
          }
        }
      },
      "Forbidden": {
        "description": "Key đã bị tắt/thu hồi (`key revoked`), hoặc model nằm ngoài danh sách model của key này.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "type": "error",
              "error": {
                "type": "permission_error",
                "message": "key is not allowed to use \"claude-opus-5-5\""
              }
            }
          }
        }
      },
      "PaymentRequired": {
        "description": "Hết credit, hoặc `max_tokens` vượt quá số dư còn lại.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "type": "error",
              "error": {
                "type": "insufficient_credit",
                "message": "not enough credit"
              }
            }
          }
        }
      },
      "ModelNotFound": {
        "description": "Model không có trong bảng giá. Chúng tôi KHÔNG fallback sang model khác.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "type": "error",
              "error": {
                "type": "not_found_error",
                "message": "model \"x\" is not available"
              }
            }
          }
        }
      },
      "RateLimited": {
        "description": "Vượt giới hạn của key: 600 request/phút (cửa sổ trượt 60 giây), 500 request đồng thời, quá nhiều lần sai key từ cùng một IP, hoặc nhà cung cấp đang rate limit. Header `retry-after` cho biết chờ bao nhiêu giây.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/Error"
            },
            "example": {
              "type": "error",
              "error": {
                "type": "rate_limit_error",
                "message": "rate limit 600 rpm exceeded"
              }
            }
          }
        }
      }
    }
  },
  "paths": {
    "/v1/models": {
      "get": {
        "tags": [
          "Models"
        ],
        "summary": "Liệt kê model và giá",
        "description": "Trả mọi model mà KEY của bạn gọi được VÀ đang có kênh khoẻ (khác với toàn bộ bảng giá). Model có giá nhưng nhà cung cấp hết kênh sẽ không xuất hiện — đúng như hành vi của `/v1/models`: không quảng cáo một lựa chọn chắc chắn trả 502. Giá trong `pricing_usd_per_1m` là giá BÁN, đơn vị credit-$ (xem `credit_vnd_per_usd`).",
        "operationId": "listModels",
        "responses": {
          "200": {
            "description": "Danh sách model",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "object": {
                      "type": "string",
                      "const": "list"
                    },
                    "credit_vnd_per_usd": {
                      "type": "number",
                      "description": "VND của 1 credit-$ (đơn vị của `pricing_usd_per_1m`). KHÔNG phải tỷ giá USD→VND của ví — ví quy đổi theo tỷ giá riêng, hiện ở trang Thanh toán."
                    },
                    "models_hidden_no_channel": {
                      "type": "integer",
                      "description": "Số model có trong bảng giá nhưng chưa có kênh nên bị ẩn khỏi danh sách. Không có mặt khi mọi model đều có kênh."
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "enum": [
                              "claude-sonnet-5-5",
                              "claude-opus-5-5",
                              "claude-haiku-4-5",
                              "claude-haiku-4-5-20251001",
                              "claude-haiku-5-5",
                              "claude-sonnet-5",
                              "claude-opus-5",
                              "claude-fable-5-1",
                              "gpt-5.4",
                              "gpt-4o-mini",
                              "gpt-6.1-sol",
                              "gpt-6.1-terra",
                              "gpt-6-astra",
                              "gpt-6-sol",
                              "gpt-6-luna",
                              "gpt-5.6-sol",
                              "gpt-5.6-luna",
                              "gpt-5.6-terra",
                              "gpt-5.5",
                              "gpt-5.4-mini",
                              "grok-4.7",
                              "grok-4.6",
                              "grok-4.5",
                              "grok-4.3",
                              "gemini-4-argon",
                              "gemini-3.1-pro-preview",
                              "gemini-3.8-flash",
                              "gemini-3.1-flash-lite",
                              "deepseek-flash"
                            ]
                          },
                          "object": {
                            "type": "string",
                            "const": "model"
                          },
                          "owned_by": {
                            "type": "string",
                            "description": "anthropic | openai | xai | gemini | compat"
                          },
                          "pricing_usd_per_1m": {
                            "$ref": "#/components/schemas/Pricing"
                          }
                        }
                      }
                    }
                  }
                },
                "example": {
                  "object": "list",
                  "credit_vnd_per_usd": 3250,
                  "data": [
                    {
                      "id": "claude-sonnet-5-5",
                      "object": "model",
                      "owned_by": "anthropic",
                      "pricing_usd_per_1m": {
                        "input": 0.23,
                        "output": 1.15,
                        "cache_read": 0.0115,
                        "cache_write_5m": 0.2875,
                        "cache_write_1h": 0.46
                      }
                    }
                  ]
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/messages": {
      "post": {
        "tags": [
          "Anthropic"
        ],
        "summary": "Tạo message (Anthropic Messages API)",
        "description": "Chỉ cần đổi `ANTHROPIC_BASE_URL` sang endpoint này — request/response giữ nguyên hình dạng của Anthropic, kể cả `stream: true` (SSE được chuyển byte-exact). Đây là đường Claude Code dùng.",
        "operationId": "createMessage",
        "security": [
          {
            "anthropicKey": []
          },
          {
            "bearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "model",
                  "max_tokens",
                  "messages"
                ],
                "properties": {
                  "model": {
                    "type": "string",
                    "enum": [
                      "claude-sonnet-5-5",
                      "claude-opus-5-5",
                      "claude-haiku-4-5",
                      "claude-haiku-4-5-20251001",
                      "claude-haiku-5-5",
                      "claude-sonnet-5",
                      "claude-opus-5",
                      "claude-fable-5-1",
                      "gpt-5.4",
                      "gpt-4o-mini",
                      "gpt-6.1-sol",
                      "gpt-6.1-terra",
                      "gpt-6-astra",
                      "gpt-6-sol",
                      "gpt-6-luna",
                      "gpt-5.6-sol",
                      "gpt-5.6-luna",
                      "gpt-5.6-terra",
                      "gpt-5.5",
                      "gpt-5.4-mini",
                      "grok-4.7",
                      "grok-4.6",
                      "grok-4.5",
                      "grok-4.3",
                      "gemini-4-argon",
                      "gemini-3.1-pro-preview",
                      "gemini-3.8-flash",
                      "gemini-3.1-flash-lite",
                      "deepseek-flash"
                    ],
                    "description": "Model id (xem GET /v1/models)."
                  },
                  "max_tokens": {
                    "type": "integer",
                    "minimum": 1,
                    "description": "Bắt buộc — Anthropic yêu cầu."
                  },
                  "messages": {
                    "type": "array",
                    "description": "Lịch sử hội thoại, cùng hình dạng của Anthropic.",
                    "items": {
                      "type": "object",
                      "required": [
                        "role",
                        "content"
                      ],
                      "properties": {
                        "role": {
                          "type": "string",
                          "enum": [
                            "user",
                            "assistant"
                          ]
                        },
                        "content": {
                          "type": [
                            "string",
                            "array"
                          ],
                          "description": "Chuỗi, hoặc mảng content block."
                        }
                      }
                    }
                  },
                  "system": {
                    "type": [
                      "string",
                      "array"
                    ],
                    "description": "System prompt."
                  },
                  "stream": {
                    "type": "boolean",
                    "default": false,
                    "description": "Bật SSE streaming."
                  },
                  "temperature": {
                    "type": "number",
                    "minimum": 0,
                    "maximum": 1
                  },
                  "top_p": {
                    "type": "number"
                  },
                  "stop_sequences": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    }
                  },
                  "tools": {
                    "type": "array",
                    "items": {
                      "type": "object"
                    },
                    "description": "Tool definition, giữ nguyên hình dạng Anthropic."
                  },
                  "tool_choice": {
                    "type": [
                      "object",
                      "string"
                    ]
                  },
                  "metadata": {
                    "type": "object"
                  }
                }
              },
              "example": {
                "model": "claude-sonnet-5-5",
                "max_tokens": 256,
                "messages": [
                  {
                    "role": "user",
                    "content": "Hello"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Message (hoặc luồng SSE nếu `stream: true`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "type": {
                      "type": "string",
                      "const": "message"
                    },
                    "role": {
                      "type": "string",
                      "const": "assistant"
                    },
                    "model": {
                      "type": "string"
                    },
                    "content": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "stop_reason": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "usage": {
                      "$ref": "#/components/schemas/Usage"
                    }
                  }
                },
                "example": {
                  "id": "msg_01",
                  "type": "message",
                  "role": "assistant",
                  "model": "claude-sonnet-5-5",
                  "content": [
                    {
                      "type": "text",
                      "text": "Hello!"
                    }
                  ],
                  "stop_reason": "end_turn",
                  "usage": {
                    "input_tokens": 8,
                    "output_tokens": 4
                  }
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string"
                },
                "example": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{…}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"delta\":{\"text\":\"Hi\"}}\n\n"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/ModelNotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/messages/count_tokens": {
      "post": {
        "tags": [
          "Anthropic"
        ],
        "summary": "Đếm token (không tính tiền)",
        "description": "Chuyển tiếp nguyên văn tới nhà cung cấp. Không bị tính tiền và không trừ credit — dùng để chặn prompt quá lớn trước khi trả tiền cho model.",
        "operationId": "countTokens",
        "security": [
          {
            "anthropicKey": []
          },
          {
            "bearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "model",
                  "messages"
                ],
                "properties": {
                  "model": {
                    "type": "string",
                    "enum": [
                      "claude-sonnet-5-5",
                      "claude-opus-5-5",
                      "claude-haiku-4-5",
                      "claude-haiku-4-5-20251001",
                      "claude-haiku-5-5",
                      "claude-sonnet-5",
                      "claude-opus-5",
                      "claude-fable-5-1",
                      "gpt-5.4",
                      "gpt-4o-mini",
                      "gpt-6.1-sol",
                      "gpt-6.1-terra",
                      "gpt-6-astra",
                      "gpt-6-sol",
                      "gpt-6-luna",
                      "gpt-5.6-sol",
                      "gpt-5.6-luna",
                      "gpt-5.6-terra",
                      "gpt-5.5",
                      "gpt-5.4-mini",
                      "grok-4.7",
                      "grok-4.6",
                      "grok-4.5",
                      "grok-4.3",
                      "gemini-4-argon",
                      "gemini-3.1-pro-preview",
                      "gemini-3.8-flash",
                      "gemini-3.1-flash-lite",
                      "deepseek-flash"
                    ]
                  },
                  "messages": {
                    "type": "array",
                    "items": {
                      "type": "object"
                    }
                  },
                  "system": {
                    "type": [
                      "string",
                      "array"
                    ]
                  },
                  "tools": {
                    "type": "array",
                    "items": {
                      "type": "object"
                    }
                  }
                }
              },
              "example": {
                "model": "claude-sonnet-5-5",
                "messages": [
                  {
                    "role": "user",
                    "content": "Hello"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Số token",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "input_tokens": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "input_tokens": 8
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          }
        }
      }
    },
    "/v1/chat/completions": {
      "post": {
        "tags": [
          "OpenAI"
        ],
        "summary": "Chat completion (OpenAI-compatible)",
        "description": "Dùng được với mọi SDK OpenAI: chỉ đổi `base_url`. `stream: true` trả SSE; chúng tôi tự thêm `stream_options.include_usage` để ghi nhận token chính xác (và bỏ nó khỏi phần trả về của bạn).",
        "operationId": "createChatCompletion",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "model",
                  "messages"
                ],
                "properties": {
                  "model": {
                    "type": "string",
                    "enum": [
                      "claude-sonnet-5-5",
                      "claude-opus-5-5",
                      "claude-haiku-4-5",
                      "claude-haiku-4-5-20251001",
                      "claude-haiku-5-5",
                      "claude-sonnet-5",
                      "claude-opus-5",
                      "claude-fable-5-1",
                      "gpt-5.4",
                      "gpt-4o-mini",
                      "gpt-6.1-sol",
                      "gpt-6.1-terra",
                      "gpt-6-astra",
                      "gpt-6-sol",
                      "gpt-6-luna",
                      "gpt-5.6-sol",
                      "gpt-5.6-luna",
                      "gpt-5.6-terra",
                      "gpt-5.5",
                      "gpt-5.4-mini",
                      "grok-4.7",
                      "grok-4.6",
                      "grok-4.5",
                      "grok-4.3",
                      "gemini-4-argon",
                      "gemini-3.1-pro-preview",
                      "gemini-3.8-flash",
                      "gemini-3.1-flash-lite",
                      "deepseek-flash"
                    ]
                  },
                  "messages": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "required": [
                        "role",
                        "content"
                      ],
                      "properties": {
                        "role": {
                          "type": "string",
                          "enum": [
                            "system",
                            "user",
                            "assistant",
                            "tool"
                          ]
                        },
                        "content": {
                          "type": [
                            "string",
                            "array",
                            "null"
                          ]
                        }
                      }
                    }
                  },
                  "stream": {
                    "type": "boolean",
                    "default": false
                  },
                  "max_tokens": {
                    "type": "integer"
                  },
                  "max_completion_tokens": {
                    "type": "integer"
                  },
                  "temperature": {
                    "type": "number"
                  },
                  "top_p": {
                    "type": "number"
                  },
                  "tools": {
                    "type": "array",
                    "items": {
                      "type": "object"
                    }
                  },
                  "tool_choice": {
                    "type": [
                      "object",
                      "string"
                    ]
                  },
                  "response_format": {
                    "type": "object"
                  }
                }
              },
              "example": {
                "model": "claude-sonnet-5-5",
                "messages": [
                  {
                    "role": "user",
                    "content": "Hello"
                  }
                ],
                "max_tokens": 256
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Chat completion (hoặc SSE nếu `stream: true`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "object": {
                      "type": "string",
                      "const": "chat.completion"
                    },
                    "model": {
                      "type": "string"
                    },
                    "choices": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    },
                    "usage": {
                      "type": "object",
                      "properties": {
                        "prompt_tokens": {
                          "type": "integer"
                        },
                        "completion_tokens": {
                          "type": "integer"
                        },
                        "total_tokens": {
                          "type": "integer"
                        }
                      }
                    }
                  }
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/ModelNotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1/responses": {
      "post": {
        "tags": [
          "OpenAI"
        ],
        "summary": "Responses API (OpenAI)",
        "description": "Endpoint mới của OpenAI. Hình dạng request/response giữ nguyên.",
        "operationId": "createResponse",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "model",
                  "input"
                ],
                "properties": {
                  "model": {
                    "type": "string",
                    "enum": [
                      "claude-sonnet-5-5",
                      "claude-opus-5-5",
                      "claude-haiku-4-5",
                      "claude-haiku-4-5-20251001",
                      "claude-haiku-5-5",
                      "claude-sonnet-5",
                      "claude-opus-5",
                      "claude-fable-5-1",
                      "gpt-5.4",
                      "gpt-4o-mini",
                      "gpt-6.1-sol",
                      "gpt-6.1-terra",
                      "gpt-6-astra",
                      "gpt-6-sol",
                      "gpt-6-luna",
                      "gpt-5.6-sol",
                      "gpt-5.6-luna",
                      "gpt-5.6-terra",
                      "gpt-5.5",
                      "gpt-5.4-mini",
                      "grok-4.7",
                      "grok-4.6",
                      "grok-4.5",
                      "grok-4.3",
                      "gemini-4-argon",
                      "gemini-3.1-pro-preview",
                      "gemini-3.8-flash",
                      "gemini-3.1-flash-lite",
                      "deepseek-flash"
                    ]
                  },
                  "input": {
                    "type": [
                      "string",
                      "array"
                    ]
                  },
                  "stream": {
                    "type": "boolean",
                    "default": false
                  },
                  "max_output_tokens": {
                    "type": "integer"
                  }
                }
              },
              "example": {
                "model": "claude-sonnet-5-5",
                "input": "Hello"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Response object (hoặc SSE nếu `stream: true`)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/ModelNotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1beta/models/{model}:generateContent": {
      "post": {
        "tags": [
          "Google"
        ],
        "summary": "Gemini generateContent",
        "description": "Hình dạng của google-genai SDK. Đổi `base_url` sang endpoint này; header auth là `x-goog-api-key` (SDK tự gửi). Chỉ model `gemini-*` đi được đường này: model Claude/OpenAI/grok gọi vào đây sẽ nhận 404 từ chính Google. Với `:streamGenerateContent` thêm `?alt=sse` (gateway tự thêm nếu thiếu).",
        "operationId": "generateContent",
        "parameters": [
          {
            "name": "model",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "claude-sonnet-5-5",
                "claude-opus-5-5",
                "claude-haiku-4-5",
                "claude-haiku-4-5-20251001",
                "claude-haiku-5-5",
                "claude-sonnet-5",
                "claude-opus-5",
                "claude-fable-5-1",
                "gpt-5.4",
                "gpt-4o-mini",
                "gpt-6.1-sol",
                "gpt-6.1-terra",
                "gpt-6-astra",
                "gpt-6-sol",
                "gpt-6-luna",
                "gpt-5.6-sol",
                "gpt-5.6-luna",
                "gpt-5.6-terra",
                "gpt-5.5",
                "gpt-5.4-mini",
                "grok-4.7",
                "grok-4.6",
                "grok-4.5",
                "grok-4.3",
                "gemini-4-argon",
                "gemini-3.1-pro-preview",
                "gemini-3.8-flash",
                "gemini-3.1-flash-lite",
                "deepseek-flash"
              ]
            },
            "description": "Model id, vd. `gemini-3.8-flash`."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "contents": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "role": {
                          "type": "string",
                          "enum": [
                            "user",
                            "model"
                          ]
                        },
                        "parts": {
                          "type": "array",
                          "items": {
                            "type": "object"
                          }
                        }
                      }
                    }
                  },
                  "systemInstruction": {
                    "type": "object"
                  },
                  "generationConfig": {
                    "type": "object"
                  }
                }
              },
              "example": {
                "contents": [
                  {
                    "role": "user",
                    "parts": [
                      {
                        "text": "Hello"
                      }
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "GenerateContentResponse",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "404": {
            "$ref": "#/components/responses/ModelNotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1beta/models/{model}:countTokens": {
      "post": {
        "tags": [
          "Google"
        ],
        "summary": "Gemini countTokens (không tính tiền)",
        "description": "Đếm token của một request trước khi gửi, để chặn prompt quá lớn. Chuyển nguyên văn tới Google và KHÔNG bị tính tiền, không trừ hạn mức — giống `POST /v1/messages/count_tokens` của Anthropic.",
        "operationId": "countTokensGemini",
        "parameters": [
          {
            "name": "model",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "claude-sonnet-5-5",
                "claude-opus-5-5",
                "claude-haiku-4-5",
                "claude-haiku-4-5-20251001",
                "claude-haiku-5-5",
                "claude-sonnet-5",
                "claude-opus-5",
                "claude-fable-5-1",
                "gpt-5.4",
                "gpt-4o-mini",
                "gpt-6.1-sol",
                "gpt-6.1-terra",
                "gpt-6-astra",
                "gpt-6-sol",
                "gpt-6-luna",
                "gpt-5.6-sol",
                "gpt-5.6-luna",
                "gpt-5.6-terra",
                "gpt-5.5",
                "gpt-5.4-mini",
                "grok-4.7",
                "grok-4.6",
                "grok-4.5",
                "grok-4.3",
                "gemini-4-argon",
                "gemini-3.1-pro-preview",
                "gemini-3.8-flash",
                "gemini-3.1-flash-lite",
                "deepseek-flash"
              ]
            },
            "description": "Model id, vd. `gemini-3.8-flash`."
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "contents": {
                    "type": "array",
                    "items": {
                      "type": "object"
                    }
                  },
                  "systemInstruction": {
                    "type": "object"
                  }
                }
              },
              "example": {
                "contents": [
                  {
                    "role": "user",
                    "parts": [
                      {
                        "text": "Hello"
                      }
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Số token",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "totalTokens": {
                      "type": "integer"
                    }
                  }
                },
                "example": {
                  "totalTokens": 3
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "404": {
            "$ref": "#/components/responses/ModelNotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    },
    "/v1beta/models/{model}:streamGenerateContent": {
      "post": {
        "tags": [
          "Google"
        ],
        "summary": "Gemini streamGenerateContent",
        "description": "Như `generateContent` nhưng trả SSE. Chúng tôi tự thêm `alt=sse` nếu request thiếu — thiếu nó thì Gemini trả JSON array và không stream được.",
        "operationId": "streamGenerateContent",
        "parameters": [
          {
            "name": "model",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "claude-sonnet-5-5",
                "claude-opus-5-5",
                "claude-haiku-4-5",
                "claude-haiku-4-5-20251001",
                "claude-haiku-5-5",
                "claude-sonnet-5",
                "claude-opus-5",
                "claude-fable-5-1",
                "gpt-5.4",
                "gpt-4o-mini",
                "gpt-6.1-sol",
                "gpt-6.1-terra",
                "gpt-6-astra",
                "gpt-6-sol",
                "gpt-6-luna",
                "gpt-5.6-sol",
                "gpt-5.6-luna",
                "gpt-5.6-terra",
                "gpt-5.5",
                "gpt-5.4-mini",
                "grok-4.7",
                "grok-4.6",
                "grok-4.5",
                "grok-4.3",
                "gemini-4-argon",
                "gemini-3.1-pro-preview",
                "gemini-3.8-flash",
                "gemini-3.1-flash-lite",
                "deepseek-flash"
              ]
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Luồng SSE",
            "content": {
              "text/event-stream": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "402": {
            "$ref": "#/components/responses/PaymentRequired"
          },
          "404": {
            "$ref": "#/components/responses/ModelNotFound"
          },
          "429": {
            "$ref": "#/components/responses/RateLimited"
          }
        }
      }
    }
  }
}
