{
  "openapi": "3.1.0",
  "info": {
    "title": "AGYStore Messages API",
    "version": "1.0.0",
    "description": "Public Anthropic-compatible Messages and Models API for AGYStore. Supports message completions, streaming via server-sent events, token estimation, and model discovery. Authenticate using Bearer token or x-api-key header. Note on Streaming, Accounting, and Retries: HTTP 200 at SSE stream start indicates that the connection has been established, NOT that full message generation has completed. Clients must handle terminal events (message_stop, error) or network interruptions. Missing, partial, or interrupted stream usage does NOT automatically imply zero charge; the gateway holds reservations and settles usage incurred up to the interruption. Clients must inspect account history and ledger state before retrying interrupted or unverified requests. The request_id is provided solely for diagnostic correlation and tracing, NOT as a caller-controlled billing idempotency fence."
  },
  "servers": [
    {
      "url": "https://api.agydev.store",
      "description": "Production AI API endpoint"
    }
  ],
  "paths": {
    "/v1/messages": {
      "post": {
        "summary": "Create a Message",
        "description": "Send a structured list of input messages and generate a model response. Supports both synchronous JSON responses and streaming via Server-Sent Events (SSE). Note: HTTP 200 at SSE stream start is not a proof of terminal generation; clients must handle terminal events (message_stop, error) or network interruption, and inspect account history before retrying. Missing, partial, or unverified streaming usage does not imply zero charge. The request_id is for correlation and diagnostics, NOT a caller-controlled billing idempotency fence. Requested max_tokens is capped by server configuration (default 8192, configured maximum 16384) rather than rejecting requests above 8192.",
        "operationId": "createMessage",
        "security": [
          {
            "BearerAuth": []
          },
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MessagesRequest"
              },
              "example": {
                "model": "claude-sonnet-5",
                "max_tokens": 1024,
                "messages": [
                  {
                    "role": "user",
                    "content": "Xin chào! Bạn có thể giúp tôi viết một hàm Python không?"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful message completion (JSON) or server-sent events stream (SSE).",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MessageResponse"
                },
                "example": {
                  "id": "msg_01X9Z8y7w6v5u4t3s2r1q0",
                  "type": "message",
                  "role": "assistant",
                  "model": "claude-sonnet-5",
                  "content": [
                    {
                      "type": "text",
                      "text": "Chào bạn! Tôi có thể giúp bạn viết hàm Python. Bạn cần thực hiện công việc gì?"
                    }
                  ],
                  "stop_reason": "end_turn",
                  "stop_sequence": null,
                  "usage": {
                    "input_tokens": 25,
                    "output_tokens": 28
                  }
                }
              },
              "text/event-stream": {
                "schema": {
                  "type": "string",
                  "description": "Server-sent events stream delivering incremental message content. Events include message_start, content_block_start, content_block_delta, content_block_stop, message_delta, and message_stop."
                },
                "example": "event: message_start\ndata: {\"type\":\"message_start\",\"message\":{\"id\":\"msg_01X9Z8y7w6v5u4t3s2r1q0\",\"type\":\"message\",\"role\":\"assistant\",\"model\":\"claude-sonnet-5\",\"content\":[],\"stop_reason\":null,\"stop_sequence\":null,\"usage\":{\"input_tokens\":25,\"output_tokens\":0}}}\n\nevent: content_block_start\ndata: {\"type\":\"content_block_start\",\"index\":0,\"content_block\":{\"type\":\"text\",\"text\":\"\"}}\n\nevent: content_block_delta\ndata: {\"type\":\"content_block_delta\",\"index\":0,\"delta\":{\"type\":\"text_delta\",\"text\":\"Chào bạn!\"}}\n\nevent: content_block_stop\ndata: {\"type\":\"content_block_stop\",\"index\":0}\n\nevent: message_delta\ndata: {\"type\":\"message_delta\",\"delta\":{\"stop_reason\":\"end_turn\",\"stop_sequence\":null},\"usage\":{\"output_tokens\":4}}\n\nevent: message_stop\ndata: {\"type\":\"message_stop\"}\n\n"
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400"
          },
          "401": {
            "$ref": "#/components/responses/Error401"
          },
          "402": {
            "$ref": "#/components/responses/Error402"
          },
          "403": {
            "$ref": "#/components/responses/Error403"
          },
          "404": {
            "$ref": "#/components/responses/Error404"
          },
          "408": {
            "$ref": "#/components/responses/Error408"
          },
          "410": {
            "$ref": "#/components/responses/Error410"
          },
          "413": {
            "$ref": "#/components/responses/Error413"
          },
          "429": {
            "$ref": "#/components/responses/Error429"
          },
          "502": {
            "$ref": "#/components/responses/Error502"
          },
          "503": {
            "$ref": "#/components/responses/Error503"
          },
          "504": {
            "$ref": "#/components/responses/Error504"
          }
        }
      }
    },
    "/v1/messages/count_tokens": {
      "post": {
        "summary": "Count Tokens",
        "description": "Count input tokens for a proposed message list and model without generating output or settling quota holds. Does not require max_tokens or stream parameters. Consumes standard per-minute request rate limits.",
        "operationId": "countTokens",
        "security": [
          {
            "BearerAuth": []
          },
          {
            "ApiKeyAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CountTokensRequest"
              },
              "example": {
                "model": "claude-sonnet-5",
                "messages": [
                  {
                    "role": "user",
                    "content": "Đếm số token cho câu hỏi này."
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Token count result.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CountTokensResponse"
                },
                "example": {
                  "input_tokens": 16
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/Error400"
          },
          "401": {
            "$ref": "#/components/responses/Error401"
          },
          "402": {
            "$ref": "#/components/responses/Error402"
          },
          "403": {
            "$ref": "#/components/responses/Error403"
          },
          "404": {
            "$ref": "#/components/responses/Error404"
          },
          "408": {
            "$ref": "#/components/responses/Error408"
          },
          "410": {
            "$ref": "#/components/responses/Error410"
          },
          "413": {
            "$ref": "#/components/responses/Error413"
          },
          "429": {
            "$ref": "#/components/responses/Error429"
          },
          "502": {
            "$ref": "#/components/responses/Error502"
          },
          "503": {
            "$ref": "#/components/responses/Error503"
          },
          "504": {
            "$ref": "#/components/responses/Error504"
          }
        }
      }
    },
    "/v1/models": {
      "get": {
        "summary": "List Models",
        "description": "List all active models available to the authenticated account or API key. Results reflect allowed account entitlements and public aliases.",
        "operationId": "listModels",
        "security": [
          {
            "BearerAuth": []
          },
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "List of available models.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModelListResponse"
                },
                "example": {
                  "data": [
                    {
                      "id": "claude-haiku-4-5",
                      "type": "model",
                      "display_name": "Claude Haiku 4.5",
                      "created_at": "2026-03-01T00:00:00Z"
                    },
                    {
                      "id": "claude-sonnet-5",
                      "type": "model",
                      "display_name": "Claude Sonnet 5",
                      "created_at": "2026-03-01T00:00:00Z"
                    }
                  ],
                  "has_more": false,
                  "first_id": "claude-haiku-4-5",
                  "last_id": "claude-sonnet-5"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error401"
          },
          "403": {
            "$ref": "#/components/responses/Error403"
          },
          "429": {
            "$ref": "#/components/responses/Error429"
          },
          "503": {
            "$ref": "#/components/responses/Error503"
          }
        }
      }
    },
    "/v1/models/{model_id}": {
      "get": {
        "summary": "Get Model Details",
        "description": "Retrieve details and metadata for a specific available model.",
        "operationId": "getModel",
        "parameters": [
          {
            "name": "model_id",
            "in": "path",
            "required": true,
            "description": "The model identifier to retrieve.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "security": [
          {
            "BearerAuth": []
          },
          {
            "ApiKeyAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "Model information.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ModelResponse"
                },
                "example": {
                  "id": "claude-sonnet-5",
                  "type": "model",
                  "display_name": "Claude Sonnet 5",
                  "created_at": "2026-03-01T00:00:00Z"
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Error401"
          },
          "403": {
            "$ref": "#/components/responses/Error403"
          },
          "404": {
            "$ref": "#/components/responses/Error404"
          },
          "429": {
            "$ref": "#/components/responses/Error429"
          },
          "503": {
            "$ref": "#/components/responses/Error503"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "API key provided as HTTP Bearer token in the Authorization header (Authorization: Bearer sk-...)."
      },
      "ApiKeyAuth": {
        "type": "apiKey",
        "in": "header",
        "name": "x-api-key",
        "description": "API key provided in the x-api-key header."
      }
    },
    "schemas": {
      "MessagesRequest": {
        "type": "object",
        "required": [
          "model",
          "messages",
          "max_tokens"
        ],
        "properties": {
          "model": {
            "type": "string",
            "description": "Model identifier (e.g. claude-opus-5, claude-sonnet-5, claude-haiku-4-5). Must be non-empty, stripped of whitespace, maximum 160 characters without control characters."
          },
          "messages": {
            "type": "array",
            "description": "Ordered list of conversation turns. Must be non-empty and contain at most 100,000 items. Supports user, assistant, and constrained system history turns.",
            "items": {
              "$ref": "#/components/schemas/Message"
            }
          },
          "max_tokens": {
            "type": "integer",
            "minimum": 1,
            "description": "The maximum number of tokens to generate before stopping. Minimum is 1; boolean values are rejected. The server caps requested max_tokens by API_MAX_OUTPUT_TOKENS (default 8192, configured maximum 16384) rather than hard-rejecting requests above 8192."
          },
          "stream": {
            "type": "boolean",
            "default": false,
            "description": "Whether to incrementally stream the response using server-sent events."
          },
          "system": {
            "description": "System prompt providing high-level context and instructions. May be a string or an array of text content blocks.",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/TextBlock"
                }
              }
            ]
          },
          "temperature": {
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "description": "Sampling temperature between 0.0 and 1.0."
          },
          "top_p": {
            "type": "number",
            "minimum": 0,
            "maximum": 1,
            "description": "Nucleus sampling parameter."
          },
          "top_k": {
            "type": "integer",
            "minimum": 0,
            "description": "Only sample from the top K options for each token."
          },
          "metadata": {
            "type": "object",
            "description": "Metadata about the request, such as user_id (string, max 256 characters).",
            "properties": {
              "user_id": {
                "type": "string"
              }
            }
          },
          "stop_sequences": {
            "type": "array",
            "description": "Custom text sequences that cause the model to stop generating.",
            "items": {
              "type": "string"
            }
          },
          "tools": {
            "type": "array",
            "description": "Definitions of tools that the model may use. Supports custom client tools, typed client tools, tool search tools, and advisor tools.",
            "items": {
              "$ref": "#/components/schemas/Tool"
            }
          },
          "tool_choice": {
            "type": "object",
            "description": "How the model should select and use tools (auto, any, or tool).",
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "auto",
                  "any",
                  "tool"
                ]
              },
              "name": {
                "type": "string"
              }
            }
          }
        }
      },
      "CountTokensRequest": {
        "type": "object",
        "required": [
          "model",
          "messages"
        ],
        "properties": {
          "model": {
            "type": "string",
            "description": "Model identifier for token estimation."
          },
          "messages": {
            "type": "array",
            "description": "Input messages to estimate tokens for.",
            "items": {
              "$ref": "#/components/schemas/Message"
            }
          },
          "system": {
            "description": "System prompt contributing to token count.",
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/TextBlock"
                }
              }
            ]
          },
          "tools": {
            "type": "array",
            "description": "Tool definitions contributing to token count.",
            "items": {
              "$ref": "#/components/schemas/Tool"
            }
          },
          "tool_choice": {
            "type": "object",
            "description": "Tool choice specification."
          }
        }
      },
      "Message": {
        "oneOf": [
          {
            "type": "object",
            "required": [
              "role",
              "content"
            ],
            "properties": {
              "role": {
                "type": "string",
                "enum": [
                  "user",
                  "assistant"
                ],
                "description": "User or assistant conversation turn. Content is strictly required."
              },
              "content": {
                "oneOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/ContentBlock"
                    }
                  }
                ]
              }
            }
          },
          {
            "type": "object",
            "required": [
              "role"
            ],
            "properties": {
              "role": {
                "type": "string",
                "enum": [
                  "system"
                ],
                "description": "Constrained system history message turn. Content may be string or array of system blocks (text, tool_addition, tool_removal); content may be omitted only when output_config is provided."
              },
              "content": {
                "oneOf": [
                  {
                    "type": "string"
                  },
                  {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/SystemContentBlock"
                    }
                  }
                ]
              },
              "clear_at": {
                "type": "string",
                "enum": [
                  "never",
                  "next_user_message"
                ],
                "description": "Context clearing policy for system history messages."
              },
              "output_config": {
                "type": "object",
                "description": "Effort level output configuration (e.g. low, medium, high, xhigh, max)."
              }
            }
          }
        ]
      },
      "SystemContentBlock": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/TextBlock"
          },
          {
            "$ref": "#/components/schemas/SystemToolAdditionBlock"
          },
          {
            "$ref": "#/components/schemas/SystemToolRemovalBlock"
          }
        ]
      },
      "SystemToolAdditionBlock": {
        "type": "object",
        "required": [
          "type",
          "tool"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "tool_addition"
            ]
          },
          "tool": {
            "type": "object",
            "description": "Tool reference or definition to add into conversation context."
          }
        }
      },
      "SystemToolRemovalBlock": {
        "type": "object",
        "required": [
          "type",
          "tool"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "tool_removal"
            ]
          },
          "tool": {
            "type": "object",
            "description": "Tool reference to remove from conversation context."
          }
        }
      },
      "ContentBlock": {
        "oneOf": [
          {
            "$ref": "#/components/schemas/TextBlock"
          },
          {
            "$ref": "#/components/schemas/ImageBlock"
          },
          {
            "$ref": "#/components/schemas/ToolUseBlock"
          },
          {
            "$ref": "#/components/schemas/ToolResultBlock"
          },
          {
            "$ref": "#/components/schemas/ThinkingBlock"
          },
          {
            "$ref": "#/components/schemas/RedactedThinkingBlock"
          },
          {
            "$ref": "#/components/schemas/ServerToolUseBlock"
          },
          {
            "$ref": "#/components/schemas/ToolReferenceBlock"
          },
          {
            "$ref": "#/components/schemas/CompactionBlock"
          },
          {
            "$ref": "#/components/schemas/McpToolListingBlock"
          },
          {
            "$ref": "#/components/schemas/AdvisorToolResultBlock"
          },
          {
            "$ref": "#/components/schemas/ToolSearchResultBlock"
          },
          {
            "$ref": "#/components/schemas/SystemToolAdditionBlock"
          },
          {
            "$ref": "#/components/schemas/SystemToolRemovalBlock"
          }
        ]
      },
      "TextBlock": {
        "type": "object",
        "required": [
          "type",
          "text"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "text"
            ]
          },
          "text": {
            "type": "string"
          }
        }
      },
      "ImageBlock": {
        "type": "object",
        "required": [
          "type",
          "source"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "image"
            ]
          },
          "source": {
            "$ref": "#/components/schemas/ImageSource"
          }
        },
        "description": "Image content block. Images are feature-dependent (API_IMAGES_ENABLED) and permitted in user-role messages only, including nested user tool_result content."
      },
      "ImageSource": {
        "description": "Image source definition. Permitted in user-role messages only. Supported formats: JPEG, PNG, GIF, WebP. Maximum 10MB decoded, maximum 8000x8000 dimensions, max 100 images per request. URLs must be public HTTPS; private/internal/loopback addresses are rejected.",
        "oneOf": [
          {
            "type": "object",
            "required": [
              "type",
              "media_type",
              "data"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "base64"
                ]
              },
              "media_type": {
                "type": "string",
                "enum": [
                  "image/jpeg",
                  "image/png",
                  "image/gif",
                  "image/webp"
                ]
              },
              "data": {
                "type": "string",
                "description": "Base64-encoded image data. Supported formats: JPEG, PNG, GIF, WebP. Maximum 10MB decoded, maximum 8000x8000 dimensions, max 100 images per request."
              }
            }
          },
          {
            "type": "object",
            "required": [
              "type",
              "url"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "url"
                ]
              },
              "url": {
                "type": "string",
                "format": "uri",
                "description": "Public HTTPS URL of the image (max 4096 chars). Localhost, loopback, private IP, internal, and port-restricted addresses are rejected."
              }
            }
          }
        ]
      },
      "ToolUseBlock": {
        "type": "object",
        "required": [
          "type",
          "id",
          "name",
          "input"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "tool_use"
            ]
          },
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "input": {
            "type": "object"
          }
        }
      },
      "ToolResultBlock": {
        "type": "object",
        "required": [
          "type",
          "tool_use_id"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "tool_result"
            ]
          },
          "tool_use_id": {
            "type": "string"
          },
          "content": {
            "oneOf": [
              {
                "type": "string"
              },
              {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/ContentBlock"
                }
              }
            ]
          },
          "is_error": {
            "type": "boolean",
            "default": false
          }
        }
      },
      "ThinkingBlock": {
        "type": "object",
        "required": [
          "type",
          "thinking",
          "signature"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "thinking"
            ]
          },
          "thinking": {
            "type": "string"
          },
          "signature": {
            "type": "string"
          }
        }
      },
      "RedactedThinkingBlock": {
        "type": "object",
        "required": [
          "type",
          "data"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "redacted_thinking"
            ]
          },
          "data": {
            "type": "string"
          }
        }
      },
      "ServerToolUseBlock": {
        "type": "object",
        "required": [
          "type",
          "id",
          "name",
          "input"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "server_tool_use"
            ]
          },
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "input": {
            "type": "object"
          }
        }
      },
      "ToolReferenceBlock": {
        "type": "object",
        "required": [
          "type",
          "tool_name"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "tool_reference"
            ]
          },
          "tool_name": {
            "type": "string"
          }
        }
      },
      "CompactionBlock": {
        "type": "object",
        "required": [
          "type"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "compaction"
            ]
          },
          "content": {
            "type": [
              "string",
              "null"
            ]
          },
          "encrypted_content": {
            "type": [
              "string",
              "null"
            ]
          },
          "signature": {
            "type": "string"
          },
          "cache_control": {
            "type": "object"
          },
          "tool_changes": {
            "type": "array"
          }
        }
      },
      "McpToolListingBlock": {
        "type": "object",
        "required": [
          "type",
          "mcp_server_name",
          "tools"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "mcp_tool_listing"
            ]
          },
          "mcp_server_name": {
            "type": "string"
          },
          "tools": {
            "type": "array"
          }
        }
      },
      "AdvisorToolResultBlock": {
        "type": "object",
        "required": [
          "type",
          "tool_use_id",
          "content"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "advisor_tool_result"
            ]
          },
          "tool_use_id": {
            "type": "string"
          },
          "content": {
            "type": "object",
            "description": "Advisor result object, such as advisor_result, advisor_redacted_result, or advisor_tool_result_error."
          }
        }
      },
      "ToolSearchResultBlock": {
        "type": "object",
        "required": [
          "type",
          "tool_use_id",
          "content"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "tool_search_tool_result"
            ]
          },
          "tool_use_id": {
            "type": "string"
          },
          "content": {
            "oneOf": [
              {
                "type": "object"
              },
              {
                "type": "array"
              }
            ],
            "description": "Tool search results, error result, or array of search result objects."
          }
        }
      },
      "Tool": {
        "oneOf": [
          {
            "type": "object",
            "required": [
              "name",
              "input_schema"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "custom"
                ]
              },
              "name": {
                "type": "string"
              },
              "description": {
                "type": "string"
              },
              "input_schema": {
                "type": "object",
                "description": "JSON Schema object defining the tool inputs."
              },
              "defer_loading": {
                "type": "boolean"
              },
              "cache_control": {
                "type": "object"
              }
            }
          },
          {
            "type": "object",
            "required": [
              "type",
              "name"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "bash_20250124",
                  "text_editor_20250124",
                  "text_editor_20250429",
                  "text_editor_20250728"
                ]
              },
              "name": {
                "type": "string"
              },
              "cache_control": {
                "type": "object"
              }
            }
          },
          {
            "type": "object",
            "required": [
              "type",
              "name"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "tool_search_tool_regex_20251119",
                  "tool_search_tool_bm25_20251119"
                ]
              },
              "name": {
                "type": "string"
              },
              "input_schema": {
                "type": "object"
              }
            }
          },
          {
            "type": "object",
            "required": [
              "type",
              "name",
              "model"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "advisor_20260301"
                ]
              },
              "name": {
                "type": "string",
                "enum": [
                  "advisor"
                ]
              },
              "model": {
                "type": "string"
              },
              "max_uses": {
                "type": "integer",
                "minimum": 1
              }
            }
          }
        ]
      },
      "MessageResponse": {
        "type": "object",
        "required": [
          "id",
          "type",
          "role",
          "content",
          "model",
          "stop_reason",
          "usage"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "message"
            ]
          },
          "role": {
            "type": "string",
            "enum": [
              "assistant"
            ]
          },
          "content": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ContentBlock"
            }
          },
          "model": {
            "type": "string"
          },
          "stop_reason": {
            "type": [
              "string",
              "null"
            ],
            "enum": [
              "end_turn",
              "max_tokens",
              "stop_sequence",
              "tool_use",
              null
            ]
          },
          "stop_sequence": {
            "type": [
              "string",
              "null"
            ]
          },
          "usage": {
            "$ref": "#/components/schemas/Usage"
          }
        }
      },
      "Usage": {
        "type": "object",
        "required": [
          "input_tokens",
          "output_tokens"
        ],
        "properties": {
          "input_tokens": {
            "type": "integer"
          },
          "output_tokens": {
            "type": "integer"
          }
        }
      },
      "CountTokensResponse": {
        "type": "object",
        "required": [
          "input_tokens"
        ],
        "properties": {
          "input_tokens": {
            "type": "integer",
            "description": "Calculated count of input tokens for the provided payload."
          }
        }
      },
      "ModelListResponse": {
        "type": "object",
        "required": [
          "data",
          "has_more"
        ],
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/ModelResponse"
            }
          },
          "has_more": {
            "type": "boolean"
          },
          "first_id": {
            "type": [
              "string",
              "null"
            ]
          },
          "last_id": {
            "type": [
              "string",
              "null"
            ]
          }
        }
      },
      "ModelResponse": {
        "type": "object",
        "required": [
          "id",
          "type",
          "display_name",
          "created_at"
        ],
        "properties": {
          "id": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "model"
            ]
          },
          "display_name": {
            "type": "string"
          },
          "created_at": {
            "type": "string"
          }
        }
      },
      "ErrorEnvelope": {
        "type": "object",
        "required": [
          "type",
          "error",
          "request_id"
        ],
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "error"
            ],
            "example": "error"
          },
          "error": {
            "type": "object",
            "required": [
              "type",
              "message"
            ],
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "invalid_request_error",
                  "authentication_error",
                  "permission_error",
                  "not_found_error",
                  "rate_limit_error",
                  "api_error",
                  "overloaded_error"
                ]
              },
              "message": {
                "type": "string",
                "description": "Sanitized error message."
              },
              "code": {
                "type": "string",
                "description": "Machine-readable error code (e.g. quota_exceeded, invalid_max_tokens, invalid_stream)."
              }
            }
          },
          "request_id": {
            "type": "string",
            "description": "Trace and correlation ID. Correlation only; does not provide billing idempotency."
          }
        }
      }
    },
    "responses": {
      "Error400": {
        "description": "Bad Request. Malformed JSON, missing required fields, or validation failure.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "type": "error",
              "error": {
                "type": "invalid_request_error",
                "message": "max_tokens là bắt buộc và phải là số nguyên dương.",
                "code": "invalid_max_tokens"
              },
              "request_id": "req_01X9Z8y7w6v5u4t3s2r1q0"
            }
          }
        }
      },
      "Error401": {
        "description": "Unauthorized. Missing, invalid, or expired API key or bearer token.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "type": "error",
              "error": {
                "type": "authentication_error",
                "message": "Khóa API không hợp lệ hoặc đã hết hạn.",
                "code": "invalid_api_key"
              },
              "request_id": "req_01X9Z8y7w6v5u4t3s2r1q1"
            }
          }
        }
      },
      "Error402": {
        "description": "Payment Required. Account quota exceeded or insufficient credits.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "type": "error",
              "error": {
                "type": "permission_error",
                "message": "Tài khoản đã sử dụng hết hạn mức token.",
                "code": "quota_exceeded"
              },
              "request_id": "req_01X9Z8y7w6v5u4t3s2r1q2"
            }
          }
        }
      },
      "Error403": {
        "description": "Forbidden. Insufficient scope or access denied.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "type": "error",
              "error": {
                "type": "permission_error",
                "message": "Khóa API không có quyền truy cập dịch vụ này.",
                "code": "insufficient_scope"
              },
              "request_id": "req_01X9Z8y7w6v5u4t3s2r1q3"
            }
          }
        }
      },
      "Error404": {
        "description": "Not Found. Requested model or resource not found.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "type": "error",
              "error": {
                "type": "invalid_request_error",
                "message": "Không tìm thấy dịch vụ AI này.",
                "code": "model_not_found"
              },
              "request_id": "req_01X9Z8y7w6v5u4t3s2r1q4"
            }
          }
        }
      },
      "Error408": {
        "description": "Request Timeout. Request body reading timed out.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "type": "error",
              "error": {
                "type": "invalid_request_error",
                "message": "Hết thời gian chờ gửi nội dung yêu cầu.",
                "code": "request_timeout"
              },
              "request_id": "req_01X9Z8y7w6v5u4t3s2r1q5"
            }
          }
        }
      },
      "Error410": {
        "description": "Gone. Service account or API key has expired.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "type": "error",
              "error": {
                "type": "invalid_request_error",
                "message": "Khóa API hoặc gói dịch vụ đã hết hạn sử dụng.",
                "code": "account_expired"
              },
              "request_id": "req_01X9Z8y7w6v5u4t3s2r1q6"
            }
          }
        }
      },
      "Error413": {
        "description": "Payload Too Large. Request body exceeds configured API_MAX_BODY_BYTES.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "type": "error",
              "error": {
                "type": "invalid_request_error",
                "message": "Dung lượng yêu cầu vượt giới hạn cho phép.",
                "code": "payload_too_large"
              },
              "request_id": "req_01X9Z8y7w6v5u4t3s2r1q7"
            }
          }
        }
      },
      "Error429": {
        "description": "Too Many Requests. Rate limit exceeded for requests per minute (RPM).",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "type": "error",
              "error": {
                "type": "rate_limit_error",
                "message": "Đã vượt số lượt sử dụng cho phép trong một phút.",
                "code": "rate_limit_exceeded"
              },
              "request_id": "req_01X9Z8y7w6v5u4t3s2r1q8"
            }
          }
        }
      },
      "Error502": {
        "description": "Bad Gateway. Upstream provider returned an error.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "type": "error",
              "error": {
                "type": "api_error",
                "message": "Hệ thống nhận được phản hồi lỗi từ nhà cung cấp dịch vụ AI.",
                "code": "upstream_error"
              },
              "request_id": "req_01X9Z8y7w6v5u4t3s2r1q9"
            }
          }
        }
      },
      "Error503": {
        "description": "Service Unavailable. Temporary capacity or rate tracking failure.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "type": "error",
              "error": {
                "type": "api_error",
                "message": "Hệ thống đang bận hoặc tạm thời không thể xử lý. Vui lòng thử lại sau.",
                "code": "service_unavailable"
              },
              "request_id": "req_01X9Z8y7w6v5u4t3s2r1qa"
            }
          }
        }
      },
      "Error504": {
        "description": "Gateway Timeout. Upstream provider request timed out.",
        "content": {
          "application/json": {
            "schema": {
              "$ref": "#/components/schemas/ErrorEnvelope"
            },
            "example": {
              "type": "error",
              "error": {
                "type": "api_error",
                "message": "Quá thời gian phản hồi từ nhà cung cấp dịch vụ AI.",
                "code": "gateway_timeout"
              },
              "request_id": "req_01X9Z8y7w6v5u4t3s2r1qb"
            }
          }
        }
      }
    }
  }
}
