---
title: "Select an existing meme template, generate captions, and return editor-ready meme variants"
method: POST
path: "/api/ai/memes/generate"
tags: ["ai-providers", "ai-captions"]
---

# Select an existing meme template, generate captions, and return editor-ready meme variants

`POST /api/ai/memes/generate`

## Request body

- object
  - `mode` 'template'
  - `prompt` string, required
  - `flow` 'text_to_meme'
  - `captionSource` 'input' | 'prompt'
  - `imageUrl` string
  - `templateId` string
  - `captions` string[]
  - `editableCaptions` MemeCaption[]
    - `id` string, required
    - `text` string, required
    - `x` number, required
    - `y` number, required
    - `fontSize` number, required
    - `rotationDeg` number
    - `hidden` boolean
    - `locked` boolean
    - `boxWidthPct` number
    - `boxHeightPct` number
    - `paddingPct` number
    - `maxLines` integer
    - `lineHeight` number
    - `backgroundEnabled` boolean
    - `backgroundColor` string
    - `backgroundOpacity` number
    - `letterSpacingEm` number
    - `shadowStrength` number
    - `color` string
    - `stroke` string
    - `fontFamily` 'impact' | 'arial' | 'poster'
    - `textAlign` 'left' | 'center' | 'right'
    - `semanticRole` 'setup' | 'contrast' | 'punchline' | 'reaction' | 'label'
    - `preferredCase` 'uppercase' | 'sentence' | 'title' | 'preserve'
    - `exampleText` string
    - `recommendedWordsMin` integer
    - `recommendedWordsMax` integer
    - `recommendedCharsMin` integer
    - `recommendedCharsMax` integer
  - `tone` 'sarcastic' | 'deadpan' | 'wholesome' | 'absurd' | 'corporate' | 'dark-lite' | 'brand'
  - `toneCues` string[]
  - `rewriteNote` string
  - `allowHeuristicFallback` boolean
  - `variantCount` number
  - `preferredProviderId` 'hyperswitch_vision' | 'onnx_local' | 'openai_vision'
  - `workspaceId` string
  - `correlationId` string

## Response `200`

Meme variant generation payload

- AiMemeGenerationSucceededResponse
  - `ok` true, required
  - `runId` string
  - `flow` 'text_to_meme', required
  - `mode` 'template', required
  - `status` 'succeeded', required
  - `variantCount` integer, required
  - `variants` MemeGenerationVariant[], required
    - `id` string, required
    - `mode` 'template', required
    - `providerId` string, required
    - `variantKind` 'template_captioned' | 'rendered_image', required
    - `memeUrl` string, nullable, required
    - `pageUrl` string, nullable, required
    - `templateName` string, nullable, required
    - `templateSlug` string, nullable
    - `sourceImageUrl` string, nullable
    - `templateSelectionStrategy` 'provided_template' | 'provided_image' | 'library_search' | 'recommendation' | 'null', nullable
    - `captionGenerationStrategy` 'openai' | 'heuristic' | 'provided' | 'null', nullable
    - `captions` MemeCaption[]
      - `id` string, required
      - `text` string, required
      - `x` number, required
      - `y` number, required
      - `fontSize` number, required
      - `rotationDeg` number
      - `hidden` boolean
      - `locked` boolean
      - `boxWidthPct` number
      - `boxHeightPct` number
      - `paddingPct` number
      - `maxLines` integer
      - `lineHeight` number
      - `backgroundEnabled` boolean
      - `backgroundColor` string
      - `backgroundOpacity` number
      - `letterSpacingEm` number
      - `shadowStrength` number
      - `color` string
      - `stroke` string
      - `fontFamily` 'impact' | 'arial' | 'poster'
      - `textAlign` 'left' | 'center' | 'right'
      - `semanticRole` 'setup' | 'contrast' | 'punchline' | 'reaction' | 'label'
      - `preferredCase` 'uppercase' | 'sentence' | 'title' | 'preserve'
      - `exampleText` string
      - `recommendedWordsMin` integer
      - `recommendedWordsMax` integer
      - `recommendedCharsMin` integer
      - `recommendedCharsMax` integer
    - `editable` boolean
    - `fallbackUsed` boolean, required
    - `attempts` object[], required
    - `estimatedCostUsd` number, required
  - `degradedFromAsync` boolean

## Other responses

- `400` — Validation error
- `429` — Daily AI quota exceeded
- `500` — Provider execution failure

---

[API](https://skmtc.net/memesio/apis/memesio-api-contracts.md) · [All operations](https://skmtc.net/memesio/apis/memesio-api-contracts/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/memesio/memesio-api-contracts/revisions/826e6edbf294/schema)
