{
  "openapi": "3.0.0",
  "info": {
    "title": "Web3GPT Skill API",
    "description": "Simple agent-first chat API for Web3GPT. Start a chat with no params, then continue with the returned chatId.\n\n## Versioning\n\nThe API is versioned in the URL path. `/api/v2` is the current major version; `/api` is an alias for it. Pin `/api/v2` to stay on this version. Within a major version, changes are additive only: new optional parameters, new response fields, new error codes. Breaking changes ship under a new path (`/api/v3`).\n\n## Deprecation\n\nWhen a version or operation is scheduled for removal, its responses carry a `Deprecation` header (RFC 9745) and a `Sunset` header (RFC 8594) with the removal date, and the change is listed in the skill guide (https://w3gpt.ai/skill.md). A deprecated version keeps working for at least 90 days after the `Deprecation` header first appears.",
    "version": "2.1.0"
  },
  "servers": [
    {
      "url": "/api/v2",
      "description": "Web3GPT API, major version 2 (pinned)"
    },
    {
      "url": "/api",
      "description": "Web3GPT API, alias for the current major version"
    }
  ],
  "components": {
    "schemas": {
      "SkillRequest": {
        "type": "object",
        "properties": {
          "agentId": {
            "type": "string",
            "description": "Optional agent ID. Defaults to the Web3GPT agent."
          },
          "chatId": {
            "type": "string",
            "description": "Optional chat ID. If omitted, a new chat is created."
          },
          "message": {
            "type": "string",
            "description": "Optional message to send to the agent."
          },
          "history": {
            "type": "boolean",
            "description": "Return full simplified history when true.",
            "default": false
          },
          "full": {
            "type": "boolean",
            "description": "Alias for history=true.",
            "default": false
          }
        }
      },
      "SkillHistoryItem": {
        "type": "object",
        "required": ["id", "role", "text"],
        "properties": {
          "id": {
            "type": "string"
          },
          "role": {
            "type": "string",
            "enum": ["user", "assistant", "system"]
          },
          "text": {
            "type": "string"
          }
        }
      },
      "SkillResponse": {
        "type": "object",
        "required": ["agentId", "chatId", "response"],
        "properties": {
          "agentId": {
            "type": "string"
          },
          "chatId": {
            "type": "string",
            "description": "Persist this value and pass it back on subsequent calls."
          },
          "response": {
            "type": "string",
            "nullable": true,
            "description": "Latest assistant response. Null when a chat is created without sending a message."
          },
          "history": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SkillHistoryItem"
            }
          }
        }
      },
      "PublicStats": {
        "type": "object",
        "required": [
          "customAgentsCreated",
          "definitions",
          "observedAt",
          "recordedDeployments"
        ],
        "properties": {
          "customAgentsCreated": {
            "type": "integer",
            "description": "Custom agent records. Built-in agents are excluded."
          },
          "definitions": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "observedAt": {
            "type": "string",
            "format": "date-time"
          },
          "recordedDeployments": {
            "type": "object",
            "required": ["byChain", "total"],
            "properties": {
              "byChain": {
                "type": "array",
                "items": {
                  "type": "object",
                  "required": [
                    "chainId",
                    "chainName",
                    "network",
                    "recordedDeployments"
                  ],
                  "properties": {
                    "chainId": {
                      "type": "integer"
                    },
                    "chainName": {
                      "type": "string"
                    },
                    "network": {
                      "type": "string",
                      "enum": ["mainnet", "testnet", "unknown"]
                    },
                    "recordedDeployments": {
                      "type": "integer"
                    }
                  }
                }
              },
              "total": {
                "type": "integer"
              }
            }
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "required": ["code", "error"],
        "properties": {
          "agentId": {
            "type": "string"
          },
          "chatId": {
            "type": "string"
          },
          "code": {
            "type": "string",
            "description": "Stable, machine-readable error code. Branch on this, not on the message.",
            "enum": [
              "invalid_body",
              "invalid_chat_id",
              "agent_not_found",
              "message_too_long",
              "rate_limited",
              "not_found",
              "internal_error"
            ]
          },
          "error": {
            "type": "string",
            "description": "Human-readable explanation of what went wrong."
          }
        }
      }
    }
  },
  "paths": {
    "/skill": {
      "get": {
        "operationId": "getSkillChat",
        "summary": "Start or inspect a skill chat",
        "description": "Call with no parameters to create a new chat and receive a chatId. Pass chatId to inspect an existing chat. Add history=true or full=true to receive the full simplified message history.",
        "parameters": [
          {
            "name": "agentId",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "chatId",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "message",
            "in": "query",
            "schema": {
              "type": "string"
            },
            "description": "Optional message to send. Use POST for larger prompts."
          },
          {
            "name": "history",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            }
          },
          {
            "name": "full",
            "in": "query",
            "schema": {
              "type": "boolean",
              "default": false
            },
            "description": "Alias for history=true."
          }
        ],
        "responses": {
          "200": {
            "description": "Skill chat response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SkillResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid chatId (invalid_chat_id) or a POST body that is not a JSON object (invalid_body)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "agentId names no agent (agent_not_found)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "413": {
            "description": "Message longer than 50,000 characters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Wait `Retry-After` seconds before retrying.",
            "headers": {
              "Retry-After": {
                "description": "Seconds until the limit resets",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "sendSkillMessage",
        "summary": "Continue a skill chat",
        "description": "Send a message to the agent. If chatId is omitted, a new chat is created automatically. The response always includes the chatId so you can keep using the same thread.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SkillRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Skill chat response",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SkillResponse"
                }
              }
            }
          },
          "400": {
            "description": "Invalid chatId (invalid_chat_id) or a POST body that is not a JSON object (invalid_body)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "agentId names no agent (agent_not_found)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "413": {
            "description": "Message longer than 50,000 characters",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded. Wait `Retry-After` seconds before retrying.",
            "headers": {
              "Retry-After": {
                "description": "Seconds until the limit resets",
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Limit": {
                "schema": {
                  "type": "integer"
                }
              },
              "X-RateLimit-Remaining": {
                "schema": {
                  "type": "integer"
                }
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Server error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      },
      "options": {
        "operationId": "skillPreflight",
        "summary": "CORS preflight",
        "description": "Browser CORS preflight. Agents never need to call this.",
        "responses": {
          "200": {
            "description": "CORS headers"
          }
        }
      }
    },
    "/stats": {
      "get": {
        "operationId": "getPublicStats",
        "summary": "Read public aggregate stats",
        "description": "Returns timestamped custom-agent and deduplicated deployment-record counts, including per-chain mainnet/testnet labels and metric definitions.",
        "responses": {
          "200": {
            "description": "Public aggregate stats",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/PublicStats"
                }
              }
            }
          }
        }
      }
    }
  }
}
