{"components":{"schemas":{"Error":{"properties":{"error":{"type":"string"}},"type":"object"},"Example":{"properties":{"template":{"type":"string"},"url":{"type":"string"}},"type":"object"},"Font":{"properties":{"_self":{"type":"string"},"alias":{"nullable":true,"type":"string"},"filename":{"type":"string"},"id":{"type":"string"}},"type":"object"},"MemeRequest":{"allOf":[{"properties":{"template_id":{"type":"string"}},"required":["template_id"],"type":"object"},{"$ref":"#/components/schemas/MemeTemplateRequest"}]},"MemeResponse":{"properties":{"url":{"type":"string"}},"type":"object"},"MemeTemplateRequest":{"properties":{"animate_text":{"description":"Type the text boxes out one after another, a character (`true` or \"characters\") or a word (\"words\") at a time (defaults the extension to gif)","oneOf":[{"type":"boolean"},{"enum":["characters","words"],"type":"string"}]},"extension":{"enum":["png","jpg","jpeg","gif","webp","mp4"],"type":"string"},"font":{"type":"string"},"redirect":{"description":"Redirect to the image instead of returning JSON","type":"boolean"},"text":{"description":"Lines of text (raw, not escape-encoded)","items":{"type":"string"},"type":"array"},"text_boxes":{"description":"Where to draw each line instead of the template's text boxes, one per line (a JSON string in a form)","items":{"$ref":"#/components/schemas/TextBox"},"type":"array"}},"type":"object"},"Template":{"properties":{"_self":{"type":"string"},"blank":{"type":"string"},"description":{"nullable":true,"type":"string"},"example":{"properties":{"text":{"items":{"type":"string"},"type":"array"},"url":{"type":"string"}},"type":"object"},"id":{"type":"string"},"keywords":{"items":{"type":"string"},"type":"array"},"lines":{"type":"integer"},"name":{"type":"string"},"overlays":{"type":"integer"},"source":{"nullable":true,"type":"string"},"styles":{"items":{"type":"string"},"type":"array"}},"type":"object"},"TextBox":{"description":"Where and how one line of text is drawn. Positions and sizes are\nfractions of the image's width and height.","properties":{"align":{"default":"center","description":"\"left\", \"center\" (default) or \"right\".","type":"string"},"anchor_x":{"default":0.0,"description":"Left edge of the box, 0 to 1 of the image width (default 0).","format":"float","type":"number"},"anchor_y":{"default":0.0,"description":"Top edge of the box, 0 to 1 of the image height (default 0).","format":"float","type":"number"},"angle":{"default":0.0,"description":"Counterclockwise rotation in degrees (default 0).","format":"float","type":"number"},"color":{"default":"white","description":"Text color, a CSS color name or hex code: \"white\" (default), \"black\", \"#FF0000\".","type":"string"},"font":{"default":"impact","description":"Font ID or alias from the fonts list (default \"impact\"). A request's `font` overrides it.","type":"string"},"scale_x":{"default":1.0,"description":"Box width, 0 to 1 of the image width (default 1). Text wraps and shrinks to fit the box.","format":"float","type":"number"},"scale_y":{"default":0.20000000298023224,"description":"Box height, 0 to 1 of the image height (default 0.2).","format":"float","type":"number"},"start":{"default":0.0,"description":"On an animated background, when the text appears, 0 to 1 of the animation (default 0). Ignored with animated text.","format":"float","type":"number"},"stop":{"default":1.0,"description":"On an animated background, when the text disappears, 0 to 1 of the animation (default 1).","format":"float","type":"number"},"style":{"default":"upper","description":"Letter case: \"upper\" (default), \"lower\", \"title\", \"capitalize\", \"swapcase\", \"mock\" (aLtErNaTiNg), \"none\" (as typed), or \"default\" (as typed, capitalizing sentences).","type":"string"}},"type":"object"}}},"info":{"description":"High-performance Rust port of memegen.link. An unauthenticated MCP endpoint is available at `/mcp`.","title":"Memegen","version":"0.1.0"},"openapi":"3.0.3","paths":{"/fonts/":{"get":{"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/Font"},"type":"array"}}},"description":"Successfully returned a list of fonts"}},"summary":"List available fonts","tags":["Fonts"]}},"/fonts/{id}":{"get":{"parameters":[{"description":"ID or alias of a font","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Font"}}},"description":"Successfully returned a specific font"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Font not found"}},"summary":"View a specific font","tags":["Fonts"]}},"/images/":{"get":{"parameters":[{"description":"Words to search for in the template name, keywords, description, or example; results are ranked best match first","in":"query","name":"filter","required":false,"schema":{"type":"string"}},{"description":"Limit results to animated templates","in":"query","name":"animated","required":false,"schema":{"type":"boolean"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/Example"},"type":"array"}}},"description":"Successfully returned a list of example memes"}},"summary":"List example memes","tags":["Images"]},"post":{"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemeRequest"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/MemeRequest"}}}},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemeResponse"}}},"description":"Successfully created a meme"},"400":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Required \"template_id\" missing in request body"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemeResponse"}}},"description":"Specified \"template_id\" does not exist"}},"summary":"Create a meme from a template","tags":["Images"]}},"/images/{template_filename}":{"get":{"parameters":[{"description":"Template ID and image extension, e.g. `fry.png`","in":"path","name":"template_filename","required":true,"schema":{"type":"string"}},{"description":"Font ID or alias (`GET /fonts/`)","in":"query","name":"font","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"image/*":{"schema":{"format":"binary","type":"string"}},"video/mp4":{"schema":{"format":"binary","type":"string"}}},"description":"Successfully displayed a template background"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Template not found"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Invalid extension or font"}},"summary":"Display a template background","tags":["Images"]}},"/images/{template_id}/{text_filepath}":{"get":{"description":"Lines are separated by `/`. Escapes: `_` space, `__` underscore, `--` dash, `~q` ?, `~a` &, `~p` %, `~h` #, `~s` /, `~b` \\, `~l` <, `~g` >, `~n` newline, `''` double quote. Use `:alias:` for emoji.","parameters":[{"description":"ID of a meme template, or `custom` (with an uploaded background) for the default top and bottom text boxes","in":"path","name":"template_id","required":true,"schema":{"type":"string"}},{"description":"Lines of text and image extension: `<line1>/<line2>.<png|jpg|gif|webp|mp4>`","in":"path","name":"text_filepath","required":true,"schema":{"type":"string"}},{"description":"Font ID or alias (`GET /fonts/`)","in":"query","name":"font","required":false,"schema":{"type":"string"}},{"description":"Type the text boxes out one after another, a character (`true` or `characters`) or a word (`words`) at a time, with eased timing in mp4, then hold the finished meme (gif, webp and mp4 only)","in":"query","name":"animate_text","required":false,"schema":{"enum":["true","characters","words"],"type":"string"}},{"description":"Where to draw each line instead of the template's text boxes: a JSON array of `TextBox` objects, one per line, e.g. `[{},{\"anchor_y\":0.8}]` for top and bottom. Fields left out take their defaults","in":"query","name":"text_boxes","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"image/*":{"schema":{"format":"binary","type":"string"}},"video/mp4":{"schema":{"format":"binary","type":"string"}}},"description":"Successfully displayed a custom meme"},"301":{"description":"Redirect to the canonical (normalized) URL"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Template not found"},"414":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Custom text too long (length >200)"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Invalid extension, font or text boxes, or animated text with png/jpg"}},"summary":"Display a custom meme","tags":["Images"]},"post":{"description":"Send an image as the request body to draw the meme on it instead of the template's background, in the template's text boxes (or `text_boxes`). Use `custom` as the template for the default top and bottom boxes. PNG, JPG, GIF (stays animated) or WebP, up to 10 MB, with one side at most 5 times the other; it's scaled so its short side is 600 px. The image is returned directly; no URL draws it. E.g. `curl --data-binary @background.png localhost:5000/images/custom/top/bottom.png -o meme.png`.","parameters":[{"description":"ID of a meme template, or `custom` (with an uploaded background) for the default top and bottom text boxes","in":"path","name":"template_id","required":true,"schema":{"type":"string"}},{"description":"Lines of text and image extension: `<line1>/<line2>.<png|jpg|gif|webp|mp4>`","in":"path","name":"text_filepath","required":true,"schema":{"type":"string"}},{"description":"Font ID or alias (`GET /fonts/`)","in":"query","name":"font","required":false,"schema":{"type":"string"}},{"description":"Type the text boxes out one after another, a character (`true` or `characters`) or a word (`words`) at a time, with eased timing in mp4, then hold the finished meme (gif, webp and mp4 only)","in":"query","name":"animate_text","required":false,"schema":{"enum":["true","characters","words"],"type":"string"}},{"description":"Where to draw each line instead of the template's text boxes: a JSON array of `TextBox` objects, one per line, e.g. `[{},{\"anchor_y\":0.8}]` for top and bottom. Fields left out take their defaults","in":"query","name":"text_boxes","required":false,"schema":{"type":"string"}}],"requestBody":{"content":{"image/*":{"schema":{"format":"binary","type":"string"}}},"required":true},"responses":{"200":{"content":{"image/*":{"schema":{"format":"binary","type":"string"}},"video/mp4":{"schema":{"format":"binary","type":"string"}}},"description":"Successfully displayed a meme on the uploaded background"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Template not found"},"413":{"description":"Background over 10 MB"},"414":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Custom text too long (length >200)"},"422":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Invalid background, extension, font or text boxes, or animated text with png/jpg"}},"summary":"Display a meme on your own background","tags":["Images"]}},"/templates/":{"get":{"parameters":[{"description":"Limit results to templates supporting animation","in":"query","name":"animated","required":false,"schema":{"type":"boolean"}},{"description":"Words to search for in the name, keywords, description, or example; results are ranked best match first","in":"query","name":"filter","required":false,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"items":{"$ref":"#/components/schemas/Template"},"type":"array"}}},"description":"Successfully returned a list of all templates"}},"summary":"List all templates","tags":["Templates"]}},"/templates/{id}":{"get":{"parameters":[{"description":"ID of a meme template","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"responses":{"200":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Template"}}},"description":"Successfully returned a specific template"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}},"description":"Template not found"}},"summary":"View a specific template","tags":["Templates"]},"post":{"parameters":[{"description":"ID of a meme template","in":"path","name":"id","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemeTemplateRequest"}},"application/x-www-form-urlencoded":{"schema":{"$ref":"#/components/schemas/MemeTemplateRequest"}}}},"responses":{"201":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemeResponse"}}},"description":"Successfully created a meme from a template"},"404":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemeResponse"}}},"description":"Template not found"}},"summary":"Create a meme from a template","tags":["Templates"]}}},"servers":[{"url":"https://memegen.dev"}]}