{
  "openapi": "3.1.0",
  "info": {
    "title": "Tang Tard Meme Factory API",
    "description": "Open API for meme creation. No API key required. Pre-load images into the meme editor via URL params or generate editor links via API.",
    "version": "1.0.0",
    "contact": {
      "name": "Smooth Brains Labs",
      "url": "https://smoothbrain.app"
    }
  },
  "servers": [
    { "url": "https://smoothbrain.app", "description": "Production" },
    { "url": "http://localhost:3000", "description": "Local development" }
  ],
  "paths": {
    "/api/v1/health": {
      "get": {
        "summary": "Health check",
        "operationId": "getHealth",
        "responses": {
          "200": {
            "description": "Service is healthy",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "status": { "type": "string", "example": "ok" },
                    "version": { "type": "string", "example": "1.0.0" },
                    "service": { "type": "string" },
                    "timestamp": { "type": "string", "format": "date-time" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/templates": {
      "get": {
        "summary": "Search meme templates",
        "operationId": "searchTemplates",
        "parameters": [
          { "name": "search", "in": "query", "schema": { "type": "string" }, "description": "Search by template name" },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "default": 100, "maximum": 200 }, "description": "Max results" }
        ],
        "responses": {
          "200": {
            "description": "List of matching templates",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "templates": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": { "type": "string" },
                          "name": { "type": "string" },
                          "url": { "type": "string", "format": "uri" },
                          "width": { "type": "integer" },
                          "height": { "type": "integer" },
                          "box_count": { "type": "integer" }
                        }
                      }
                    },
                    "count": { "type": "integer" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/templates/{id}": {
      "get": {
        "summary": "Get template by ID",
        "operationId": "getTemplate",
        "parameters": [
          { "name": "id", "in": "path", "required": true, "schema": { "type": "string" } }
        ],
        "responses": {
          "200": {
            "description": "Template details with editor URLs",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": { "type": "string" },
                    "name": { "type": "string" },
                    "url": { "type": "string", "format": "uri" },
                    "width": { "type": "integer" },
                    "height": { "type": "integer" },
                    "editorUrl": { "type": "string" },
                    "editorUrlTard": { "type": "string" },
                    "editorUrlChad": { "type": "string" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/memes/render": {
      "post": {
        "summary": "Generate editor URL with pre-loaded image and config",
        "operationId": "renderMeme",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "image": { "type": "string", "format": "uri", "description": "Direct image URL (any host)" },
                  "template": { "type": "string", "description": "Imgflip template name to search" },
                  "mode": { "type": "string", "enum": ["tard", "chad"], "default": "tard" },
                  "topText": { "type": "string", "description": "Pre-fill top caption" },
                  "bottomText": { "type": "string", "description": "Pre-fill bottom caption" }
                }
              },
              "examples": {
                "directImage": {
                  "summary": "Direct image URL",
                  "value": { "image": "https://example.com/template.jpg", "mode": "tard" }
                },
                "templateSearch": {
                  "summary": "Template name search",
                  "value": { "template": "drake", "mode": "chad", "topText": "Writing docs", "bottomText": "Writing memes" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Editor URL generated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "editorUrl": { "type": "string", "description": "Relative editor path" },
                    "fullUrl": { "type": "string", "format": "uri", "description": "Full URL to open in browser" },
                    "params": { "type": "object" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/memes/caption": {
      "post": {
        "summary": "Generate AI captions for an image (BYOK — pass your own API key)",
        "operationId": "captionMeme",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["image", "provider", "apiKey"],
                "properties": {
                  "image": { "type": "string", "format": "uri", "description": "URL of the image to caption" },
                  "provider": { "type": "string", "enum": ["gemini", "openai", "anthropic", "openrouter", "xai", "meta", "groq", "together", "mistral", "deepseek", "fireworks", "local", "custom"], "description": "AI provider" },
                  "apiKey": { "type": "string", "description": "Your AI provider API key (used once, never stored)" },
                  "model": { "type": "string", "description": "Specific model ID (optional)" },
                  "topic": { "type": "string", "default": "Funny/Relatable", "description": "Caption context/topic" },
                  "roastMode": { "type": "boolean", "default": false, "description": "Enable savage captions" },
                  "endpoint": { "type": "string", "description": "Custom endpoint URL (for custom/local providers)" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Generated captions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "captions": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "topText": { "type": "string" },
                          "bottomText": { "type": "string" }
                        }
                      }
                    },
                    "editorUrl": { "type": "string", "description": "Editor URL pre-filled with first caption" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/memes/imagine": {
      "post": {
        "summary": "Generate an AI image from a prompt (BYOK — pass your own API key)",
        "operationId": "imagineMeme",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["prompt", "provider", "apiKey"],
                "properties": {
                  "prompt": { "type": "string", "description": "Description of the image to generate" },
                  "provider": { "type": "string", "enum": ["gemini", "openai", "openrouter", "xai"], "description": "AI provider (must support image generation)" },
                  "apiKey": { "type": "string", "description": "Your AI provider API key (used once, never stored)" },
                  "model": { "type": "string", "description": "Specific model ID (optional)" },
                  "endpoint": { "type": "string", "description": "Custom endpoint URL (for custom/local providers)" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Generated image",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "image": { "type": "string", "description": "Base64 data URI of the generated image" }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/v1/memes/render-image": {
      "post": {
        "summary": "Render a meme as an SVG image with text overlays",
        "operationId": "renderMemeImage",
        "description": "Returns an SVG image with the source image embedded as base64 and styled text overlaid. No AI key needed. Supports custom fonts, colors, outlines, and auto-scaling.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["image"],
                "properties": {
                  "image": { "type": "string", "description": "Source image URL" },
                  "topText": { "type": "string", "description": "Top caption text (supports \\n for multiline)" },
                  "bottomText": { "type": "string", "description": "Bottom caption text" },
                  "width": { "type": "integer", "description": "Output width in px (auto-detected from image if omitted)" },
                  "font": {
                    "type": "object",
                    "properties": {
                      "family": { "type": "string", "default": "Bangers" },
                      "size": { "type": "integer", "default": 80 },
                      "fill": { "type": "string", "default": "#FFFFFF" },
                      "outlineColor": { "type": "string", "default": "#000000" },
                      "outlineWidth": { "type": "integer", "default": 5 },
                      "lineHeight": { "type": "number", "default": 1.2 },
                      "align": { "type": "string", "enum": ["left", "center", "right"], "default": "center" }
                    }
                  }
                }
              },
              "example": {
                "image": "https://i.imgflip.com/30b1gx.jpg",
                "topText": "TOP TEXT",
                "bottomText": "BOTTOM TEXT"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "SVG meme image",
            "content": {
              "image/svg+xml": {
                "schema": { "type": "string" }
              }
            }
          },
          "400": { "description": "Missing or invalid image field" },
          "413": { "description": "Image too large (>8MB)" },
          "502": { "description": "Failed to fetch source image" }
        }
      }
    },
    "/api/v1/memes/auto": {
      "post": {
        "summary": "Full pipeline: analyze image, generate captions, return editor URL (BYOK)",
        "operationId": "autoMeme",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["image", "provider"],
                "properties": {
                  "image": { "type": "string", "format": "uri", "description": "URL of the image" },
                  "provider": { "type": "string", "enum": ["gemini", "openai", "anthropic", "openrouter", "xai", "meta", "groq", "together", "mistral", "deepseek", "fireworks", "local", "custom"], "description": "AI provider" },
                  "apiKey": { "type": "string", "description": "Your AI provider API key (required for cloud providers)" },
                  "model": { "type": "string", "description": "Specific model ID (optional)" },
                  "mode": { "type": "string", "enum": ["tard", "chad"], "default": "tard" },
                  "topic": { "type": "string", "description": "Caption context hint" },
                  "endpoint": { "type": "string", "description": "Custom endpoint URL (for custom/local providers)" }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Auto-generated meme with captions and editor URL",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "templateMatch": { "type": "string", "description": "Matched template name or 'use-as-is'" },
                    "captions": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "topText": { "type": "string" },
                          "bottomText": { "type": "string" }
                        }
                      }
                    },
                    "editorUrl": { "type": "string" },
                    "fullUrl": { "type": "string", "format": "uri" }
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}
