# Kimi Web Fetch

> Common

Submit a web fetch request. `model` is fixed to `kimi-tools-fetch-custom` and is used only for routing
(stripped before forwarding); `url` is the target page, forwarded to the upstream as-is.

## Endpoint

`POST https://api.modelverse.cn/v1/tools/fetch`

## Request Body

## Responses

- **200** — Fetch result containing the URL, Markdown content and page title.
- **default** — Error response (gateway-side validation/auth errors or upstream non-200, passed through
with the original status code and body).

Common upstream errors:

| HTTP status | error.type | Description |
|---|---|---|
| 400 | `invalid_request` | Request body is not valid JSON |
| 400 | `invalid_url` | URL is empty, missing host, or not http/https |
| 401 | - | API key missing or invalid (no error body) |
| 403 | `security_risk` | URL flagged by upstream security controls; use another URL |
| 404 | `markdown_not_found` | No extractable text content on the page |
| 408 | `client_canceled` | Client disconnected before the server responded |
| 429 | `rate_limited` | Rate/concurrency limit hit; `X-RateLimit-Limit` and `X-RateLimit-Remaining` headers are returned, plus `X-RateLimit-Reset` for per-second limits |
| 429 | `rate_limit_unavailable` | Rate limit store temporarily unavailable; retry later |
| 500 | `internal_error` | Upstream internal error; retry later |
| 502 | `upstream_failed` | Upstream temporarily unavailable; retry later |
| 504 | `timeout` | Fetch timed out; retry later |


## OpenAPI Definition

```json
{
  "openapi": "3.1.0",
  "x-language": "en-US",
  "info": {
    "title": "ModelVerse Kimi Tools Fetch API",
    "version": "1.0.0",
    "description": "Self-contained OpenAPI 3.1 schema for the ModelVerse **Kimi (Moonshot) tools fetch** model.\nUnified endpoint `POST /v1/tools/fetch`; the `model` field in the body selects the provider\n(stripped before forwarding). It fetches the web page at the given URL and returns the page\ntitle with the body in Markdown format — for reading, research and content-extraction scenarios.\nThe response is non-streaming JSON, forwarded and returned as-is without normalization.\nBilling: each successful call counts as 1; upstream failures and pages with no extractable\ncontent (HTTP 200 but blank markdown) are not billed.\nSecurity: `url` must use the http/https protocol and resolve to a public address; the gateway\nblocks requests targeting internal/reserved ranges (SSRF protection).\n"
  },
  "servers": [
    {
      "url": "https://api.modelverse.cn",
      "description": "ModelVerse API endpoint."
    }
  ],
  "tags": [
    {
      "name": "Tools Fetch",
      "description": "Web page fetching."
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/v1/tools/fetch": {
      "post": {
        "tags": [
          "Tools Fetch"
        ],
        "operationId": "createKimiToolsFetch",
        "summary": "Kimi Web Fetch",
        "description": "Submit a web fetch request. `model` is fixed to `kimi-tools-fetch-custom` and is used only for routing\n(stripped before forwarding); `url` is the target page, forwarded to the upstream as-is.\n",
        "security": [
          {
            "bearerAuth": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ToolsFetchRequest"
              },
              "examples": {
                "fetch": {
                  "summary": "Fetch a web page",
                  "value": {
                    "model": "kimi-tools-fetch-custom",
                    "url": "https://platform.kimi.com/docs/api/overview"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Fetch result containing the URL, Markdown content and page title.",
            "headers": {
              "X-Msh-Track-Id": {
                "$ref": "#/components/headers/MshTrackId"
              },
              "X-Msh-Chat-Id": {
                "$ref": "#/components/headers/MshChatId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ToolsFetchResponse"
                },
                "examples": {
                  "result": {
                    "summary": "Fetch result",
                    "value": {
                      "url": "https://platform.kimi.com/docs/api/overview",
                      "markdown": "# API Overview\n\nEntry point of the Kimi API platform documentation.\n\n![image1](https://platform.kimi.com/assets/logo/dark.svg)",
                      "title": "API Overview - Kimi API Platform"
                    }
                  }
                }
              }
            }
          },
          "default": {
            "description": "Error response (gateway-side validation/auth errors or upstream non-200, passed through\nwith the original status code and body).\n\nCommon upstream errors:\n\n| HTTP status | error.type | Description |\n|---|---|---|\n| 400 | `invalid_request` | Request body is not valid JSON |\n| 400 | `invalid_url` | URL is empty, missing host, or not http/https |\n| 401 | - | API key missing or invalid (no error body) |\n| 403 | `security_risk` | URL flagged by upstream security controls; use another URL |\n| 404 | `markdown_not_found` | No extractable text content on the page |\n| 408 | `client_canceled` | Client disconnected before the server responded |\n| 429 | `rate_limited` | Rate/concurrency limit hit; `X-RateLimit-Limit` and `X-RateLimit-Remaining` headers are returned, plus `X-RateLimit-Reset` for per-second limits |\n| 429 | `rate_limit_unavailable` | Rate limit store temporarily unavailable; retry later |\n| 500 | `internal_error` | Upstream internal error; retry later |\n| 502 | `upstream_failed` | Upstream temporarily unavailable; retry later |\n| 504 | `timeout` | Fetch timed out; retry later |\n",
            "headers": {
              "X-Msh-Track-Id": {
                "$ref": "#/components/headers/MshTrackId"
              },
              "X-Msh-Chat-Id": {
                "$ref": "#/components/headers/MshChatId"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ToolsFetchErrorResponse"
                },
                "examples": {
                  "invalidUrl": {
                    "summary": "Invalid URL",
                    "value": {
                      "error": {
                        "message": "The provided URL is invalid: only http and https are supported",
                        "type": "invalid_url",
                        "code": "invalid_url"
                      }
                    }
                  },
                  "securityRisk": {
                    "summary": "Security risk",
                    "value": {
                      "error": {
                        "message": "We consider the current URL poses a security risk and are unable to provide fetch service at this time.",
                        "type": "security_risk",
                        "code": "security_risk"
                      }
                    }
                  },
                  "markdownNotFound": {
                    "summary": "No extractable content",
                    "value": {
                      "error": {
                        "message": "No text/markdown content found for the current URL.",
                        "type": "markdown_not_found",
                        "code": "markdown_not_found"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "API key",
        "description": "API key issued by the platform, passed via `Authorization: Bearer <API Key>`."
      }
    },
    "headers": {
      "MshTrackId": {
        "description": "Upstream request ID, carried on every response (including errors) and passed through as-is; provide it when reporting issues.",
        "schema": {
          "type": "string"
        }
      },
      "MshChatId": {
        "description": "Upstream session ID, fixed to `toolgw-{X-Msh-Track-Id}`; provide it together with the track ID when reporting issues.",
        "schema": {
          "type": "string"
        }
      }
    },
    "schemas": {
      "ToolsFetchRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "model",
          "url"
        ],
        "properties": {
          "model": {
            "type": "string",
            "const": "kimi-tools-fetch-custom",
            "description": "Routing identifier, fixed to `kimi-tools-fetch-custom`; stripped before forwarding."
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "URL of the page to fetch; http/https only, and must be a public address."
          }
        }
      },
      "ToolsFetchResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "url",
          "markdown",
          "title"
        ],
        "properties": {
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Fetched URL."
          },
          "markdown": {
            "type": "string",
            "description": "Fetched content in Markdown. Text and images are concatenated in page order;\nimages are embedded as `![imageN](url)` placeholders and sections are separated\nby blank lines.\n"
          },
          "title": {
            "type": "string",
            "description": "Page title."
          }
        }
      },
      "ToolsFetchErrorResponse": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "$ref": "#/components/schemas/ToolsFetchError"
          }
        }
      },
      "ToolsFetchError": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "message",
          "type",
          "code"
        ],
        "properties": {
          "message": {
            "type": "string",
            "description": "Human-readable error description."
          },
          "type": {
            "type": "string",
            "description": "Machine-readable error type (e.g. `invalid_url`, `security_risk`, `markdown_not_found`, `rate_limited`, `timeout`).",
            "examples": [
              "invalid_url"
            ]
          },
          "code": {
            "type": "string",
            "description": "Machine-readable error code, same as type.",
            "examples": [
              "invalid_url"
            ]
          }
        }
      }
    }
  }
}
```
