{"openapi":"3.1.0","info":{"title":"Supermeme.ai Meme API","version":"2.0.0","description":"Generate memes, meme captions, and minimalist illustrations from text. Human docs: https://supermeme.ai/meme-api · Agent-friendly markdown: GET /llms.txt · Note: generated image URLs are signed and expire after 1 hour."},"servers":[{"url":"https://app.supermeme.ai","description":"Production"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"API key from https://supermeme.ai/account/developers"}},"schemas":{"TextToMemeResponse":{"type":"object","properties":{"memes":{"type":"array","items":{"type":"object","properties":{"caption":{"type":"string","description":"Generated caption for this template"},"image":{"type":"string","format":"uri","description":"Public URL of the blank meme template"}},"required":["caption","image"]},"description":"Caption + template pairs; render the caption onto the template yourself"},"searchEmotion":{"type":"string","description":"Emotion/action detected in the input text"},"originalText":{"type":"string","description":"The input text, echoed back"},"generatedCaptions":{"type":"array","items":{"type":"string"},"description":"All generated captions"},"languageCode":{"type":"string","description":"Detected language of the input text","example":"English"}},"required":["memes","searchEmotion","originalText","generatedCaptions","languageCode"]},"ErrorResponse":{"type":"object","properties":{"status":{"type":"number","description":"HTTP status code","example":400},"type":{"type":"string","enum":["validation_error","unauthorized","forbidden","not_found","conflict","quota_exceeded","internal_error","service_unavailable"],"description":"Machine-readable error code","example":"validation_error"},"message":{"type":"string","description":"Human-readable error message"},"error":{"type":"string","description":"Additional error detail (5xx only)"},"correlationId":{"type":"string","description":"Include this id when contacting support"},"timestamp":{"type":"string","description":"ISO 8601 timestamp of the error"}},"required":["status","type","message","timestamp"]},"MemeImagesResponse":{"type":"object","properties":{"memes":{"type":"array","items":{"type":"string","format":"uri"},"description":"Signed URLs of the generated meme images (captions are rendered into the image)"},"expiresAt":{"type":"string","description":"Conservative ISO 8601 expiry for the returned image URLs (signed with a 1-hour TTL). The URLs are guaranteed valid until this time; treat them as expired after it.","example":"2026-01-01T13:00:00.000Z"}},"required":["memes","expiresAt"]},"SearchTemplatesResponse":{"type":"object","properties":{"templates":{"type":"array","items":{"type":"string","format":"uri"},"description":"Public URLs of matching blank meme templates (top 20)"}},"required":["templates"]},"MinimalistVisualResponse":{"type":"object","properties":{"images":{"type":"array","items":{"type":"string","format":"uri"},"description":"Signed URLs of the generated minimalist illustrations"},"expiresAt":{"type":"string","description":"Conservative ISO 8601 expiry for the returned image URLs (signed with a 1-hour TTL). The URLs are guaranteed valid until this time; treat them as expired after it.","example":"2026-01-01T13:00:00.000Z"}},"required":["images","expiresAt"]}},"parameters":{}},"paths":{"/health":{"get":{"operationId":"get__health","responses":{"200":{"description":"Successful response."}}}},"/api/v1/meme/text":{"post":{"tags":["Meme"],"summary":"Convert text to memes","description":"Generates meme captions paired with blank template URLs, for rendering the text yourself or letting a human pick. Template URLs are public and do not expire.","security":[{"bearerAuth":[]}],"operationId":"post_ConvertTextToMeme","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":2500,"description":"Text to convert to memes (max 2,500 characters)","example":"When the code works on the first try"}},"required":["text"]}}}},"responses":{"200":{"description":"Memes generated successfully","headers":{"X-RateLimit-Limit":{"description":"Request quota for the current billing period","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current billing period. Intentionally conservative: a small server-side grace buffer may accept a few more requests after this reaches 0, but treat 0 as stop.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the quota resets","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TextToMemeResponse"}}}},"400":{"description":"Bad request — invalid or missing parameters (`type: validation_error`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API key (`type: unauthorized`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The subscription does not include API access (`type: forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Monthly request quota exhausted (`type: quota_exceeded`). The `X-RateLimit-Reset` header says when the quota resets.","headers":{"X-RateLimit-Limit":{"description":"Request quota for the current billing period","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current billing period. Intentionally conservative: a small server-side grace buffer may accept a few more requests after this reaches 0, but treat 0 as stop.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the quota resets","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error (`type: internal_error`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/meme/image":{"post":{"tags":["Meme V2"],"summary":"Generate meme images v2","description":"Generates ready-to-use meme images with captions rendered in. Returned URLs are signed and expire after 1 hour (see `expiresAt`) — download or re-host promptly.","security":[{"bearerAuth":[]}],"operationId":"post_GenerateMemeImagesV2","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":2500,"description":"Text to convert to meme images (max 2,500 characters)","example":"When the code works on the first try"},"count":{"type":"number","description":"Number of memes to generate, up to 12 (optional). Normalized server-side: non-integer values are truncated, values above 12 are clamped to 12, values below 1 are rejected."},"aspectRatio":{"type":"string","enum":["1:1","3:4","4:3","9:16","16:9"],"description":"Aspect ratio for the generated images (optional)"},"paddingColor":{"type":"string","pattern":"^#([0-9A-F]{3}){1,2}$","description":"Hex color for aspect ratio padding (optional, defaults to #FFFFFF)"}},"required":["text"]}}}},"responses":{"200":{"description":"Meme images generated successfully","headers":{"X-RateLimit-Limit":{"description":"Request quota for the current billing period","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current billing period. Intentionally conservative: a small server-side grace buffer may accept a few more requests after this reaches 0, but treat 0 as stop.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the quota resets","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemeImagesResponse"}}}},"400":{"description":"Bad request — invalid or missing parameters (`type: validation_error`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API key (`type: unauthorized`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The subscription does not include API access (`type: forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Monthly request quota exhausted (`type: quota_exceeded`). The `X-RateLimit-Reset` header says when the quota resets.","headers":{"X-RateLimit-Limit":{"description":"Request quota for the current billing period","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current billing period. Intentionally conservative: a small server-side grace buffer may accept a few more requests after this reaches 0, but treat 0 as stop.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the quota resets","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error (`type: internal_error`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/search":{"get":{"tags":["Search"],"summary":"Search meme templates","description":"Search for blank meme templates by query. Returned template URLs are public and do not expire.","security":[{"bearerAuth":[]}],"operationId":"get_SearchMemeTemplates","parameters":[{"schema":{"type":"string","minLength":1,"description":"Search query for meme templates","example":"success"},"required":true,"name":"query","in":"query"}],"responses":{"200":{"description":"Templates found successfully","headers":{"X-RateLimit-Limit":{"description":"Request quota for the current billing period","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current billing period. Intentionally conservative: a small server-side grace buffer may accept a few more requests after this reaches 0, but treat 0 as stop.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the quota resets","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SearchTemplatesResponse"}}}},"400":{"description":"Bad request — invalid or missing parameters (`type: validation_error`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API key (`type: unauthorized`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The subscription does not include API access (`type: forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Monthly request quota exhausted (`type: quota_exceeded`). The `X-RateLimit-Reset` header says when the quota resets.","headers":{"X-RateLimit-Limit":{"description":"Request quota for the current billing period","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current billing period. Intentionally conservative: a small server-side grace buffer may accept a few more requests after this reaches 0, but treat 0 as stop.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the quota resets","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error (`type: internal_error`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v1/minimalist-visual":{"post":{"tags":["Minimalist Visual"],"summary":"Generate minimalist visual from text","description":"Generates minimalistic visual illustrations from a user text or idea. Returned URLs are signed and expire after 1 hour (see `expiresAt`) — download or re-host promptly.","security":[{"bearerAuth":[]}],"operationId":"post_GenerateMinimalistVisual","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":2500,"description":"The text or idea to visualize"},"count":{"type":"number","minimum":1,"maximum":3,"description":"Number of visuals to generate (1-3, default: 1)"},"aspectRatio":{"type":"string","enum":["1:1","3:4","4:3","9:16","16:9"],"description":"Aspect ratio for the generated images (default: 1:1)"}},"required":["text"]}}}},"responses":{"200":{"description":"Visuals generated successfully","headers":{"X-RateLimit-Limit":{"description":"Request quota for the current billing period","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current billing period. Intentionally conservative: a small server-side grace buffer may accept a few more requests after this reaches 0, but treat 0 as stop.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the quota resets","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MinimalistVisualResponse"}}}},"400":{"description":"Bad request — invalid or missing parameters (`type: validation_error`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API key (`type: unauthorized`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The subscription does not include API access (`type: forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Monthly request quota exhausted (`type: quota_exceeded`). The `X-RateLimit-Reset` header says when the quota resets.","headers":{"X-RateLimit-Limit":{"description":"Request quota for the current billing period","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current billing period. Intentionally conservative: a small server-side grace buffer may accept a few more requests after this reaches 0, but treat 0 as stop.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the quota resets","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error (`type: internal_error`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/api/v2/meme/image":{"post":{"tags":["Meme V2"],"summary":"Generate meme images v2","description":"Generates ready-to-use meme images with captions rendered in. Returned URLs are signed and expire after 1 hour (see `expiresAt`) — download or re-host promptly.","security":[{"bearerAuth":[]}],"operationId":"post_GenerateMemeImagesV2","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"text":{"type":"string","minLength":1,"maxLength":2500,"description":"Text to convert to meme images (max 2,500 characters)","example":"When the code works on the first try"},"count":{"type":"number","description":"Number of memes to generate, up to 12 (optional). Normalized server-side: non-integer values are truncated, values above 12 are clamped to 12, values below 1 are rejected."},"aspectRatio":{"type":"string","enum":["1:1","3:4","4:3","9:16","16:9"],"description":"Aspect ratio for the generated images (optional)"},"paddingColor":{"type":"string","pattern":"^#([0-9A-F]{3}){1,2}$","description":"Hex color for aspect ratio padding (optional, defaults to #FFFFFF)"}},"required":["text"]}}}},"responses":{"200":{"description":"Meme images generated successfully","headers":{"X-RateLimit-Limit":{"description":"Request quota for the current billing period","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current billing period. Intentionally conservative: a small server-side grace buffer may accept a few more requests after this reaches 0, but treat 0 as stop.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the quota resets","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MemeImagesResponse"}}}},"400":{"description":"Bad request — invalid or missing parameters (`type: validation_error`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Missing or invalid API key (`type: unauthorized`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"The subscription does not include API access (`type: forbidden`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Monthly request quota exhausted (`type: quota_exceeded`). The `X-RateLimit-Reset` header says when the quota resets.","headers":{"X-RateLimit-Limit":{"description":"Request quota for the current billing period","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Requests remaining in the current billing period. Intentionally conservative: a small server-side grace buffer may accept a few more requests after this reaches 0, but treat 0 as stop.","schema":{"type":"integer"}},"X-RateLimit-Reset":{"description":"Unix timestamp (seconds) when the quota resets","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Internal server error (`type: internal_error`)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}},"webhooks":{}}