{
  "openapi": "3.1.0",
  "info": {
    "title": "asciify.art Public API",
    "version": "1.0.0",
    "description": "Public HTTP API for the asciify.art ASCII art generator. No authentication required. Public IP-based rate limiting applies to the MCP endpoint.",
    "contact": {
      "name": "asciify.art",
      "url": "https://asciify.art"
    },
    "license": {
      "name": "MIT"
    }
  },
  "servers": [
    {
      "url": "https://asciify.art",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "text",
      "description": "Generate FIGlet-style ASCII text banners"
    },
    { "name": "gallery", "description": "Public gallery of shared ASCII art" },
    {
      "name": "export",
      "description": "Export ASCII art to distributable formats"
    },
    { "name": "system", "description": "Operational endpoints" },
    { "name": "agent", "description": "Endpoints designed for AI agents (MCP)" }
  ],
  "paths": {
    "/api/text": {
      "get": {
        "tags": ["text"],
        "summary": "List available FIGlet fonts",
        "responses": {
          "200": {
            "description": "Fonts list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "fonts": { "type": "array", "items": { "type": "string" } },
                    "usage": { "type": "string" }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["text"],
        "summary": "Generate an ASCII banner from text",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["text"],
                "properties": {
                  "text": {
                    "type": "string",
                    "description": "Input text. Use \\n for line breaks."
                  },
                  "font": {
                    "type": "string",
                    "default": "Standard",
                    "description": "FIGlet font name. See GET /api/text for valid values."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Generated banner",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "banner": { "type": "string" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" },
          "500": { "$ref": "#/components/responses/ServerError" }
        }
      }
    },
    "/api/gallery": {
      "get": {
        "tags": ["gallery"],
        "summary": "List public gallery items",
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "schema": { "type": "integer", "minimum": 1, "default": 1 }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 50,
              "default": 20
            }
          },
          {
            "name": "sort",
            "in": "query",
            "schema": {
              "type": "string",
              "enum": ["newest", "popular", "trending"],
              "default": "newest"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Paginated gallery",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "items": {
                      "type": "array",
                      "items": { "$ref": "#/components/schemas/GalleryItem" }
                    },
                    "pagination": {
                      "type": "object",
                      "properties": {
                        "page": { "type": "integer" },
                        "limit": { "type": "integer" },
                        "total": { "type": "integer" },
                        "totalPages": { "type": "integer" },
                        "hasMore": { "type": "boolean" }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "post": {
        "tags": ["gallery"],
        "summary": "Submit an ASCII artwork to the public gallery",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["asciiArt"],
                "properties": {
                  "asciiArt": { "type": "string" },
                  "title": { "type": "string", "maxLength": 100 },
                  "width": { "type": "integer" },
                  "charset": {
                    "type": "string",
                    "enum": ["simple", "detailed", "blocks", "dots", "minimal"]
                  },
                  "sourceType": {
                    "type": "string",
                    "enum": ["banner", "image"]
                  },
                  "font": { "type": "string" },
                  "color": { "type": "string" },
                  "effect": { "type": "string" },
                  "scanlines": { "type": "boolean" },
                  "glowIntensity": { "type": "number" },
                  "effectSpeed": { "type": "number" },
                  "shadow3d": { "type": "boolean" },
                  "isPublic": { "type": "boolean", "default": true }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": { "type": "string" },
                    "shareUrl": { "type": "string" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/BadRequest" }
        }
      }
    },
    "/api/gallery/{id}": {
      "get": {
        "tags": ["gallery"],
        "summary": "Fetch a single gallery item and increment views",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": { "type": "string" }
          }
        ],
        "responses": {
          "200": {
            "description": "Gallery item",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "item": { "$ref": "#/components/schemas/GalleryItem" }
                  }
                }
              }
            }
          },
          "404": { "$ref": "#/components/responses/NotFound" }
        }
      }
    },
    "/api/export/html": {
      "post": {
        "tags": ["export"],
        "summary": "Export ASCII art as a zipped HTML+CSS bundle",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["asciiArt"],
                "properties": {
                  "asciiArt": { "type": "string" },
                  "textColor": { "type": "string" },
                  "backgroundColor": { "type": "string" },
                  "glowColor": { "type": "string" },
                  "glowIntensity": { "type": "number" },
                  "includeScanlines": { "type": "boolean" },
                  "includeGlow": { "type": "boolean" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Zip archive",
            "content": {
              "application/zip": {
                "schema": { "type": "string", "format": "binary" }
              }
            }
          }
        }
      }
    },
    "/api/health": {
      "get": {
        "tags": ["system"],
        "summary": "Health check",
        "responses": {
          "200": {
            "description": "Healthy",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": { "type": "string", "example": "ok" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/version": {
      "get": {
        "tags": ["system"],
        "summary": "Deployed application version",
        "responses": {
          "200": {
            "description": "Version info",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "version": { "type": "string" },
                    "buildTime": { "type": "string" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/mcp": {
      "post": {
        "tags": ["agent"],
        "summary": "MCP Streamable HTTP endpoint",
        "description": "JSON-RPC 2.0 over HTTP implementing the Model Context Protocol. See /.well-known/mcp/server-card.json for capabilities. Rate-limited to 10 requests per minute per IP. Batch arrays are limited to 20 requests. Public — no authentication required.",
        "externalDocs": {
          "description": "MCP server guide and client setup",
          "url": "https://asciify.art/mcp"
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "JSON-RPC 2.0 request envelope"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JSON-RPC 2.0 response",
            "content": {
              "application/json": {
                "schema": { "type": "object" }
              }
            }
          },
          "400": {
            "description": "Parse error or invalid request (e.g. empty batch or more than 20 batched requests)"
          },
          "429": {
            "description": "Rate limit exceeded"
          }
        }
      },
      "get": {
        "tags": ["agent"],
        "summary": "MCP transport discovery",
        "responses": {
          "200": {
            "description": "Transport info"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "GalleryItem": {
        "type": "object",
        "properties": {
          "id": { "type": "string" },
          "createdAt": { "type": "string", "format": "date-time" },
          "asciiArt": { "type": "string" },
          "title": { "type": "string", "nullable": true },
          "width": { "type": "integer" },
          "charset": { "type": "string" },
          "sourceType": { "type": "string" },
          "font": { "type": "string", "nullable": true },
          "color": { "type": "string" },
          "effect": { "type": "string", "nullable": true },
          "scanlines": { "type": "boolean" },
          "glowIntensity": { "type": "number" },
          "effectSpeed": { "type": "number" },
          "shadow3d": { "type": "boolean" },
          "views": { "type": "integer" },
          "likes": { "type": "integer" }
        }
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Invalid request",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": { "error": { "type": "string" } }
            }
          }
        }
      },
      "NotFound": {
        "description": "Not found",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": { "error": { "type": "string" } }
            }
          }
        }
      },
      "ServerError": {
        "description": "Server error",
        "content": {
          "application/json": {
            "schema": {
              "type": "object",
              "properties": { "error": { "type": "string" } }
            }
          }
        }
      }
    }
  }
}
