---
title: "Generate safety-approved caption reroll options with atomically enforced daily quota"
method: POST
path: "/api/ai/captions/generate"
tags: ["ai-captions"]
---

# Generate safety-approved caption reroll options with atomically enforced daily quota

`POST /api/ai/captions/generate`

## Request body

- object
  - `tone` string, required
  - `memeId` string
  - `memeSlug` string
  - `ownerToken` string
  - `sceneSummary` string
  - `entities` string[]
  - `toneCues` string[]
  - `trendReferences` string[]
  - `trendKeywords` string[]
  - `rewriteNote` string
  - `referenceCaptions` string[]
  - `captionCount` integer
  - `optionCount` integer
  - `variationOffset` integer

## Response `200`

Caption generation + ranking payload with reroll quota snapshot

- object
  - `ok` boolean
  - `generationStrategy` 'openai' | 'heuristic'
  - `providerId` string
  - `fallbackUsed` boolean
  - `quota` union
    - object
      - `kind` 'caption_proposals', required
      - `available` true, required
      - `used` integer, required
      - `limit` 3, required
      - `remaining` integer, required
      - `resetAt` string, date-time, required
      - `reset` CaptionProposalsQuotaReset, required
        - `at` string, date-time, required
        - `window` 'utc_day', required
        - `timezone` 'UTC', required
      - `actor` 'guest' | 'user_unverified' | 'user_verified', required
      - `exhausted` boolean, required
    - object
      - `kind` 'caption_proposals', required
      - `available` false, required
      - `used` unknown, required
      - `limit` 3, required
      - `remaining` unknown, required
      - `resetAt` unknown, required
      - `reset` unknown, required
      - `actor` 'guest' | 'user_unverified' | 'user_verified' | 'null', nullable, required
      - `exhausted` unknown, required
      - `errorCode` 'caption_quota_unavailable' | 'caption_dependency_unavailable' | 'developer_api_keys_unavailable' | 'agent_api_keys_unavailable', required
  - `captionSets` object[]
    - `id` string
    - `score` number
    - `captions` object[]
      - `text` string

## Other responses

- `400` — Validation error
- `403` — State-changing request origin is not allowed
- `422` — Generation returned no complete safety-approved proposals
- `429` — Burst rate limit or daily caption quota exceeded; body includes an absolute resetAt timestamp
- `503` — Quota storage, provider, or safety dependency unavailable after documented charge-on-attempt handling

---

[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)
