Memes.ai Memes.ai API Beta v1 · 2026-06-18 Studio ↗

Betav1 endpoints are open for early integrations. Additive fields may ship before GA.

The ad-creative API for builders.

Turn a brand and an idea into finished, on-brand creative — meme ads, images, short-form video, carousels, storyboards. The same engine behind studio.memes.media, as a clean REST API. One key, one async pattern, a handful of calls to a campaign.

Images & memes

Brand-grounded ad images, 1–4 variants, with edits, inpaint, and reframe.

Short-form video

Text-to-video and image-to-video — animate any asset you generate.

Carousels & storyboards

Free strategy plan, then render multi-slide carousels and narrative storyboards.

Brand kits & audits

Reusable brand profiles that ground every call, plus website-grounded audits.

Three ideas, and you know the whole API

One async patternEvery creative call returns a Generation you poll (or receive by webhook). You never block on a render.
One asset shapeEvery output — image, video, slide, analysis — is the same normalized Asset. Write your handling once.
One brand contextPass a brand_kit_id (or inline brand_context) to any endpoint and the output is on-brand by construction.

Quickstart

Generate your first meme in two calls. Create a key in API settings, then:

1 · Generate

Every creative call is asynchronous. You get an immediate 202 with a queued job.

curl https://api.memes.media/v1/memes \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 3f1c9a52-0e9b-4b8d-9a1a-1f2e3d4c5b6a" \
  -d '{
    "prompt": "When the coffee finally kicks in on a Monday",
    "brand_context": { "company_name": "Dawn Roasters", "industry": "coffee" },
    "aspect_ratio": "1:1",
    "count": 2
  }'
const res = await fetch("https://api.memes.media/v1/memes", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.MEMES_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    prompt: "When the coffee finally kicks in on a Monday",
    brand_context: { company_name: "Dawn Roasters", industry: "coffee" },
    aspect_ratio: "1:1",
    count: 2,
  }),
});
const { generation } = await res.json();
console.log(generation.id); // gen_8f3k1m2p7q
import os, uuid, requests

res = requests.post(
    "https://api.memes.media/v1/memes",
    headers={
        "Authorization": f"Bearer {os.environ['MEMES_API_KEY']}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "prompt": "When the coffee finally kicks in on a Monday",
        "brand_context": {"company_name": "Dawn Roasters", "industry": "coffee"},
        "aspect_ratio": "1:1",
        "count": 2,
    },
)
generation = res.json()["generation"]
print(generation["id"])  # gen_8f3k1m2p7q

2 · Poll for the result

Poll the unified Generations endpoint until status is terminal. In production, register a webhook instead.

curl https://api.memes.media/v1/generations/gen_8f3k1m2p7q \
  -H "Authorization: Bearer sk_live_YOUR_KEY"
{
  "generation": {
    "id": "gen_8f3k1m2p7q",
    "type": "meme",
    "status": "succeeded",
    "model": "forge-image",
    "completed_count": 2,
    "output": [
      { "id": "asset_a1", "type": "image", "url": "https://cdn.memes.media/a1.png", "aspect_ratio": "1:1", "width": 1024, "height": 1024 },
      { "id": "asset_a2", "type": "image", "url": "https://cdn.memes.media/a2.png", "aspect_ratio": "1:1", "width": 1024, "height": 1024 }
    ],
    "completed_at": "2026-06-18T17:04:41Z"
  },
  "usage": { "credits_used": 2, "credits_remaining": 478 },
  "meta": { "request_id": "req_b2c4", "livemode": true }
}

That's the entire loop: submit → poll → use output[]. It's identical for images, video, carousels, and storyboards — only the request body changes.

A complete campaign

A realistic flow: save a brand once, generate variants, then resize the winner for Stories. Watch each id thread into the next call — a brand_kit_id grounds the generation, and an output[].id (asset_…) becomes the input to the reframe.

# 1 · Save the brand once — the returned id is reusable forever
curl https://api.memes.media/v1/brand-kits \
  -H "Authorization: Bearer sk_live_YOUR_KEY" -H "Content-Type: application/json" \
  -d '{ "name": "Dawn Roasters", "company_name": "Dawn Roasters",
        "website_url": "https://dawnroasters.example",
        "brand_colors": ["#3B2A1A", "#E8C39E"], "tone_of_voice": "warm, witty" }'
# -> { "brand_kit": { "id": "bk_dawn_roasters", ... } }

# 2 · Generate four on-brand variants
curl https://api.memes.media/v1/memes \
  -H "Authorization: Bearer sk_live_YOUR_KEY" -H "Content-Type: application/json" \
  -H "Idempotency-Key: 9b1d..." \
  -d '{ "prompt": "POV: cold brew the night before a deadline",
        "brand_kit_id": "bk_dawn_roasters", "count": 4 }'
# -> { "generation": { "id": "gen_8f3k1m2p7q", "status": "queued" } }

# 3 · Poll until terminal
curl https://api.memes.media/v1/generations/gen_8f3k1m2p7q \
  -H "Authorization: Bearer sk_live_YOUR_KEY"
# -> status "succeeded", output: [ { "id": "asset_a1", ... }, ... ]

# 4 · Reframe the winner for Stories — any output asset can be reused as an input
curl https://api.memes.media/v1/images/reframe \
  -H "Authorization: Bearer sk_live_YOUR_KEY" -H "Content-Type: application/json" \
  -d '{ "image_id": "asset_a1", "aspect_ratio": "9:16" }'

From here, animate the winner into video (POST /videos/animate), or fan out a carousel from the same brand kit. Every output asset is reusable as the next call's input.

Authentication

The API authenticates with secret keys sent as a bearer token.

curl https://api.memes.media/v1/account \
  -H "Authorization: Bearer sk_live_YOUR_KEY"
Live keyssk_live_… — bill and affect your live workspace.
Test keyssk_test_… — run the same code paths in a sandbox; outputs are watermarked.
VisibilityThe full secret is shown once at creation. We store only a one-way hash.
RotationCreate a new key, deploy it, then revoke the old one. Revocation is immediate.

Every key belongs to a workspace. The livemode boolean on every response tells you which mode a key is in.

Keep keys server-side. Secret keys grant full access to a workspace's generation and billing — never embed them in browser, mobile, or other client-side code. If a key leaks, revoke it immediately. A missing or invalid key returns 401 authentication_error.

Making requests

Base URL & versioning

All requests go to https://api.memes.media/v1. The major version is in the path; breaking changes ship as /v2 and never under you. Pin dated, backwards-compatible refinements with a header:

Memes-Version: 2026-06-18

Idempotency

Safely retry any POST with an Idempotency-Key header (a UUID per logical operation). We cache the first response for 24 hours and replay it on retries — a dropped connection never double-charges or double-generates. Reusing a key with a different body returns 409 idempotency_conflict.

Rate limits

Each key gets a sliding-window limit. Every response carries the current state:

RateLimit-Limit: 120
RateLimit-Remaining: 118
RateLimit-Reset: 41

Exceeding it returns 429 rate_limited with a Retry-After header. This is separate from your credit quota — hitting your plan's credit ceiling returns 429 quota_exceeded instead.

Pagination

List endpoints are cursor-paginated and consistent everywhere.

curl "https://api.memes.media/v1/memes?limit=40&starting_after=asset_a2" \
  -H "Authorization: Bearer sk_live_YOUR_KEY"
{ "data": [ /* ... */ ], "has_more": true, "next_cursor": "asset_xy9" }
ParamTypeDescription
limitintegerPage size, 1–100. Default 40.
starting_afterstringObject id to start after (from next_cursor).
qstringFree-text search, ≤200 chars, where supported.
orderenumnewest (default) or oldest.

The cursor is always the id of the last object in the page you received — pass it as starting_after for the next page, and stop when has_more is false.

Generations

A Generation is the single resource behind every long-running operation. Whether you render one image or a ten-slide carousel, you get a Generation and read results from it.

Lifecycle

POST /v1/<resource>          ->  202  { generation: { status: "queued" } }
GET  /v1/generations/{id}    ->  200  { generation: { status, output } }
webhook generation.completed ->  push (optional)

Status values

StatusMeaning
queuedAccepted and credits reserved; not started yet.
processingActively rendering.
succeededAll requested outputs produced.
partialSome of N outputs succeeded; unfilled credits are refunded.
failedTerminal failure; reserved credits are refunded.
canceledCanceled before completion.

succeeded, partial, failed, and canceled are terminal — stop polling once you reach one.

Credits

Credits are reserved when a job is queued and settle when it completes — you're charged only for delivered outputs, and reserved credits are refunded on failed, canceled, or the unfilled part of a partial. That's why a job reads credits_used: 0 at submit and the final figure once terminal. Every response carries a usage block: { credits_used, credits_remaining, interval, reset_at }.

The Generation object

{
  "id": "gen_8f3k1m2p7q",
  "object": "generation",
  "type": "meme",
  "status": "succeeded",
  "model": "forge-image",
  "requested_count": 4,
  "completed_count": 4,
  "failed_count": 0,
  "output": [ /* Asset objects */ ],
  "error": null,
  "created_at": "2026-06-18T17:04:22Z",
  "completed_at": "2026-06-18T17:04:53Z"
}

type is one of meme, image, edit, reframe, video, carousel, storyboard.

The Asset object

Every output, for every endpoint, has the same shape:

{
  "id": "asset_a1",
  "type": "image",
  "url": "https://cdn.memes.media/a1.png",
  "thumbnail_url": "https://cdn.memes.media/a1_thumb.png",
  "aspect_ratio": "1:1",
  "width": 1024,
  "height": 1024,
  "slide_index": null,
  "parent_id": null,
  "model": "forge-image",
  "created_at": "2026-06-18T17:04:41Z"
}

type is image, video, carousel_slide, or analysis. slide_index is set for carousel slides; parent_id links edits and reframes to their source.

Endpoints

GET/generationsList jobs; filter by type and status
GET/generations/{id}Poll any job; normalized output
POST/generations/{id}/cancelCancel a queued or processing job

Poll every 2–3s and stop at the first terminal status. Images and memes typically finish in 10–30s, video in 1–4 minutes. In production, prefer a webhook.

Models

Set model to pick a model, or omit it for the smart default per endpoint. Models belong to the Forge family — each named by capability, with a faster -fast variant where one is offered.

ModelBest for
forge-imagePrimary text-to-image ad creative; reference, product, and logo conditioning. default for Images & Memes
forge-image-fastFaster, cheaper image generation — quick variants and iteration.
forge-editInstruction edits, mask inpainting, and aspect-ratio reframing.
forge-videoText-to-video and multi-reference (2–4 image) video.
forge-motionImage-to-video — animate a single existing asset.
forge-promptPrompt enhancement — rough idea to production-ready brief.
forge-planCarousel strategy planning.
forge-copy-fastFast brand/creative analysis (e.g. URL analysis).

Most endpoints pick the right model for you — you only set model to choose between forge-image and forge-image-fast. A Forge id routes to the best available engine and fails over automatically; your code references only the stable id, and we improve what's behind it without changing the contract.

Errors

The API uses conventional HTTP status codes and returns a single error envelope.

{
  "error": {
    "type": "invalid_request_error",
    "code": "missing_required_param",
    "message": "Either prompt, brand_context, or reference_images is required.",
    "param": "prompt",
    "request_id": "req_8f2a1c"
  }
}
HTTPTypeCommon codesWhen
400invalid_request_errormissing_required_param, invalid_aspect_ratioMalformed or missing input.
401authentication_errorinvalid_api_key, revoked_api_keyBad or missing key.
403permission_errorinsufficient_scope, plan_feature_unavailableKey lacks a scope, or feature not on plan.
404not_found_errorresource_not_foundUnknown or unowned id.
409conflict_erroridempotency_conflictIdempotency reuse with a new body.
422generation_errorcontent_blocked, generation_failedSafety block or render failure.
429rate_limit_errorrate_limitedPer-key rate limit. See Retry-After.
429quota_errorquota_exceededCredit or feature quota exhausted.
500api_errorinternal_errorUnexpected error on our side.
503service_unavailabletemporarily_unavailableAt capacity; retry shortly.

Retry around 429 (respect Retry-After) and 503 (exponential backoff). 400404 aren't retryable without changes.

Webhooks

Skip polling: register an HTTPS endpoint and we'll POST a signed event when a job reaches a terminal state.

EventFires when
generation.completedA job succeeded.
generation.partialA job finished with some outputs.
generation.failedA job failed or timed out.
generation.canceledA job was canceled.

Payload

{
  "id": "evt_2x9k",
  "type": "generation.completed",
  "created_at": "2026-06-18T17:04:53Z",
  "livemode": true,
  "data": { "generation": { /* full Generation object */ } }
}

Verifying signatures

Every delivery is signed with your endpoint's secret (whsec_…, shown once) and carries svix-id, svix-timestamp, and svix-signature headers. The simplest way to verify is the official libraries — JS/TS, Python, Go, Rust, Ruby, PHP, Java, C#, and more:

import { Webhook } from "svix"; // npm install svix

const wh = new Webhook(process.env.MEMES_WEBHOOK_SECRET); // whsec_…
// Pass the RAW request body + the svix-* headers.
const event = wh.verify(rawBody, {
  "svix-id": req.headers["svix-id"],
  "svix-timestamp": req.headers["svix-timestamp"],
  "svix-signature": req.headers["svix-signature"],
}); // throws on bad signature or stale timestamp
from svix.webhooks import Webhook  # pip install svix

wh = Webhook(os.environ["MEMES_WEBHOOK_SECRET"])  # whsec_…
event = wh.verify(raw_body, {
    "svix-id": headers["svix-id"],
    "svix-timestamp": headers["svix-timestamp"],
    "svix-signature": headers["svix-signature"],
})  # raises on bad signature or stale timestamp

To verify manually: svix-signature is a space-separated list of v1,<base64> signatures, each HMAC-SHA256(secret, "{svix-id}.{svix-timestamp}.{raw_body}") over the base64 bytes after the whsec_ prefix; reject if |now − svix-timestamp| > 5 minutes. Deliveries are at-least-once — dedupe on svix-id. Failed deliveries retry with backoff for ~24h and are replayable from your webhook portal.

Managing endpoints

GET/webhooksList endpoints
POST/webhooksRegister; returns the signing secret once
PATCH/webhooks/{id}Update url, events, enabled
DEL/webhooks/{id}Remove an endpoint
POST/webhooks/{id}/testSend a test event
curl https://api.memes.media/v1/webhooks \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/hooks/memes",
    "events": ["generation.completed", "generation.failed"]
  }'

Images

Generate and edit ad images from a prompt, a brand context, and up to four reference images.

POST/imagesText-to-image / reference-conditioned (1–4)
POST/images/editsInstruction edit / mask inpaint
POST/images/reframeOutpaint to a new aspect ratio
GET/imagesList generated images
GET/images/{id}Fetch one image asset

Create an image

POST /images

ParamTypeDescription
promptstringone of*Creative direction.
brand_kit_idstringone of*A saved brand kit to ground the image.
brand_contextobjectone of*Inline brand profile if you have no kit.
reference_imagesarrayoptionalUp to 4 { type, source }; type is ref/template/logo, source is an https URL or asset id.
aspect_ratioenumoptionalauto, 1:1 (default), 4:5, 3:4, 16:9, 9:16, 2:3, 3:2, 21:9, …
countintegeroptionalVariants, 1–4. Default 1.
qualityenumoptionalfast, standard (default), premium.
modelenumoptionalforge-image (default) or forge-image-fast.

* At least one of prompt, brand_kit_id/brand_context, or reference_images.

Reuse outputs as inputs. Any output[].id (asset_…) from a previous generation can be passed as a reference_images[].source, an image_id for edits/reframes, or to animate — so you can iterate without re-uploading.

curl https://api.memes.media/v1/images \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Minimalist product hero on a sunlit kitchen counter",
    "brand_kit_id": "bk_dawn_roasters",
    "reference_images": [{ "type": "logo", "source": "https://yourcdn.example/logo.png" }],
    "aspect_ratio": "4:5",
    "count": 3
  }'

Returns 202 with a Generation (type: "image"). Credits: 1 per delivered image.

Edit & reframe

POST /images/edits applies a natural-language instruction (≤2000 chars) to an image_id, optionally within a mask (a PNG data: URL) for inpainting. POST /images/reframe outpaints an image_id into a new aspect_ratio. Both return 202; the new asset's parent_id points to the source. Credits: 1 each.

Memes

Memes are the flagship branded-ad format: a brand-grounded image with full edit/reframe lineage. Functionally they're Images with meme defaults plus lineage fields.

POST/memesGenerate 1–4 brand-grounded meme ads
GET/memesList memes
GET/memes/{id}Fetch one meme
GET/memes/{id}/lineageFull edit/reframe family tree
DEL/memes/{id}Soft-delete a meme

Create memes

ParamTypeDescription
promptstringone of*The joke, angle, or message.
brand_kit_id / brand_contextstring / objectone of*Brand grounding.
template_promptstringoptionalA meme-template directive to anchor the format.
reference_imagesarrayoptionalUp to 4 typed references.
aspect_ratioenumoptionalDefault 1:1.
countintegeroptional1–4. Default 1.
enhancebooleanoptionalRun prompt enhancement first.

* At least one of prompt, brand_kit_id/brand_context, or template_prompt.

curl https://api.memes.media/v1/memes \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "POV: you discover cold brew the night before a deadline",
    "brand_kit_id": "bk_dawn_roasters",
    "count": 4,
    "enhance": true
  }'

Returns 202 (type: "meme"). Credits: 1 per delivered variant. GET /memes/{id}/lineage returns the root plus every edit and reframe in chronological order.

Videos

Generate short-form video from text, references, or an existing image.

POST/videosText-to-video or reference-to-video
POST/videos/animateImage-to-video from an existing asset
GET/videosList video jobs
GET/videos/{id}Fetch one video
DEL/videos/{id}Delete a video (refunds credits)

Create a video

ParamTypeDescription
promptstringone of*What the video shows.
business_urlstringone of*A website to ground the concept.
brand_kit_id / brand_contextstring / objectone of*Brand grounding.
reference_imagesarrayoptionalUp to 4; their presence routes to reference-to-video.
aspect_ratioenumoptional16:9 (default), 9:16, 1:1, 4:3, 3:4, …
durationintegeroptionalSeconds, 1–15. Default 5.
resolutionenumoptional480p or 720p (default).

The model (forge-video or forge-motion) is selected automatically from your inputs.

curl https://api.memes.media/v1/videos \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A latte poured in slow motion, steam rising, warm morning light",
    "brand_kit_id": "bk_dawn_roasters",
    "aspect_ratio": "9:16",
    "duration": 6
  }'

Returns 202 (type: "video"). Credits: 10 per completed video. Video takes 1–4 minutes — use a webhook. POST /videos/animate takes an image_id and runs at 5s / 720p with forge-motion.

Carousels

Two steps by design: a free strategy plan, then a billable render that fans out one image per slide.

POST/carousels/planSlide strategy (no images, free)
POST/carouselsRender: fan out N slide jobs
GET/carouselsList carousel sets
GET/carousels/{id}Set + per-slide status and URLs
DEL/carousels/{id}Soft-delete a set

Plan a carousel

ParamTypeDescription
briefstringrequiredWhat the carousel should accomplish, ≤2500 chars.
goalenumoptionalawareness, leads (default), sales, followers, engagement.
platformenumoptionalig-portrait, ig-square, linkedin, tiktok.
slide_countintegeroptional3–10. Default 5.
brand_kit_id / brand_contextstring / objectoptionalBrand grounding.
curl https://api.memes.media/v1/carousels/plan \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "brief": "5 myths about cold brew, debunked, for first-time buyers",
    "goal": "leads",
    "platform": "ig-portrait",
    "slide_count": 5,
    "brand_kit_id": "bk_dawn_roasters"
  }'
{
  "plan": {
    "id": "plan_71kd",
    "concept_title": "Cold Brew Myths, Busted",
    "viral_mechanic": "myth/fact reveal",
    "cta": "Try the starter kit",
    "slides": [
      { "slide_index": 0, "role": "hook", "on_image_text": "5 cold brew myths" }
    ]
  },
  "model": "forge-plan"
}

Planning returns 200 synchronously (it's free). To render, POST /carousels with a plan_id (or inline plan) — it returns 202 (type: "carousel") and slides stream into output[] as they complete. Credits: 1 × slide_count.

Storyboards

A storyboard is a single composite 3–4 panel narrative ad image (not a fan-out).

POST/storyboardsGenerate one multi-panel storyboard
ParamTypeDescription
goalstringone of*What the story should land.
brand_kit_id / brand_contextstring / objectone of*Brand grounding.
presetenumoptionalauto, problem-solution, before-after, how-it-works, customer-journey, testimonial-sequence, founder-story.
panel_countintegeroptional3 or 4. Default 3.
aspect_ratioenumoptional16:9, 9:16, 1:1.
visual_styleenumoptionalcomic-strip or clean-storyboard.
toneenumoptionalNarrative tone, e.g. playful, bold, warm, professional.
text_densityenumoptionalminimal, balanced, rich.
product_roleenumoptionalHow prominently the product features.
reference_imagesarrayoptionalUp to 4 typed references.

* At least one of goal or brand_kit_id / brand_context.

curl https://api.memes.media/v1/storyboards \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "goal": "Show how cold brew goes from beans to glass in 3 steps",
    "brand_kit_id": "bk_dawn_roasters",
    "preset": "how-it-works",
    "panel_count": 3
  }'

Returns 202 (type: "storyboard"). Credits: 4.

Brand Kits

Reusable brand profiles — logo, colors, voice, audience, products — that ground any generation. Free and unlimited on every plan.

GET/brand-kitsList kits
POST/brand-kitsCreate a kit
GET/brand-kits/{id}Fetch a kit
PATCH/brand-kits/{id}Partial update
DEL/brand-kits/{id}Delete a kit
POST/brand-kits/{id}/logoUpload or replace the logo
DEL/brand-kits/{id}/logoRemove the logo
POST/brand-kits/{id}/product-referencesAdd a product reference (max 5)
DEL/brand-kits/{id}/product-references/{ref_id}Remove a product reference
POST/brand-kits/{id}/set-defaultMark the default kit
POST/brand-kits/analyze-urlExtract a profile from a URL (no save)

Create a brand kit

ParamTypeDescription
namestringrequiredA label for the kit.
company_namestringoptionalBrand name.
website_urlstringoptionalBrand site.
brand_colorsstring[]optionalHex colors.
tone_of_voicestringoptionalVoice description.
target_audiencestringoptionalAudience description.
website_contextstringoptionalPositioning notes.
industrystringoptionalIndustry.
auto_attach_product_referencesbooleanoptionalAuto-pull product images from the site. Default true.
curl https://api.memes.media/v1/brand-kits \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Dawn Roasters",
    "company_name": "Dawn Roasters",
    "website_url": "https://dawnroasters.example",
    "brand_colors": ["#3B2A1A", "#E8C39E"],
    "tone_of_voice": "warm, witty, unpretentious"
  }'
{
  "brand_kit": {
    "id": "bk_dawn_roasters",
    "object": "brand_kit",
    "name": "Dawn Roasters",
    "is_default": false,
    "created_at": "2026-06-18T17:00:00Z"
  }
}

The returned id is what you pass as brand_kit_id everywhere else. POST /brand-kits/analyze-url with { "url": "https://…" } returns an extracted profile without saving it — great for pre-filling. Synchronous 200.

Prompt Enhancement

Turn a rough idea into a polished, production-ready creative prompt.

POST/prompts/enhanceRough idea → polished image prompt
curl https://api.memes.media/v1/prompts/enhance \
  -H "Authorization: Bearer sk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "prompt": "funny ad about mondays and coffee", "website_url": "https://dawnroasters.example" }'
{
  "enhanced_prompt": "A weary office worker slumped at a desk Monday morning, transformed mid-sip...",
  "original_prompt": "funny ad about mondays and coffee",
  "model": "forge-prompt"
}

Synchronous 200. Pass has_logo, has_reference_image, and aspect_ratio to tailor the result to your intended render.

Images as inputs

You don't upload files to use an image as a reference, mask, or edit source — pass an https URL or a workspace asset id and the API fetches and normalizes it server-side. A source (in reference_images[]) or an image_id/mask accepts:

https URLYour own hosted asset URL, or any public image URL.
workspace asset idAny asset_… from a previous generation's output[] (or a meme/image id you own) — feed a generated image straight back in, no re-upload.
"reference_images": [
  { "type": "logo", "source": "https://yourcdn.example/logo.png" },
  { "type": "ref",  "source": "asset_5Tk8wQ" }
]

Presigned uploads (POST /files) for raw local bytes are coming soon. Until then, host the image and pass its URL — every input path already fetches and normalizes URLs for you.

Account & Usage

Read your workspace's plan and current consumption.

GET/accountWorkspace, plan, key prefix, livemode
GET/account/usageCredit consumption + quota by interval
curl https://api.memes.media/v1/account/usage \
  -H "Authorization: Bearer sk_live_YOUR_KEY"
{
  "plan": "pro",
  "credits_remaining": 480,
  "intervals": {
    "images": { "limit": 1000, "used": 520, "remaining": 480, "interval": "rolling_30_days", "reset_at": "2026-07-01T00:00:00Z" },
    "video":  { "limit": 50,   "used": 4,   "remaining": 46,  "interval": "rolling_30_days", "reset_at": "2026-07-01T00:00:00Z" }
  }
}

SDKs & MCP

TypeScript & Python SDKs soon

Typed clients with automatic retries, idempotency, and a webhook-signature helper.

MCP server soon

Every operation as a Model Context Protocol tool — generate_meme, generate_video, plan_carousel, get_generation — so agents can build campaigns directly.

Until the SDKs ship, the API is plain REST — any HTTP client works. Want early access to a key, an SDK, or the MCP server? Email members@memes.com.

Cookbook

Real things you can build with the API — point your Shopify, Google Sheet, or Notion catalog at it, spin up Meta creative tests, animate Reels. Pick a card for the exact setup. These are starting points for inspiration, not a limit — building something or have a wild integration in mind? We'd love to help or just hear about it: members@memes.com. Also as plain Markdown.

© 2026 Memes.ai · Built on studio.memes.media Back to top ↑
Copied