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.

Studio account required. API keys are created inside an AI Studio workspace. Create a Studio account, open the Developers tab under Manage, then create a Live or Test key.

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

Reusable brand profiles and URL analysis that ground every creative call.

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

To use the API, first create or sign into an AI Studio workspace. API keys live in the Studio Developers tab.

1 · Create an account and API key

Create accountNew to Memes.ai? Create a Studio account. We'll send you into the Developers tab after signup.
Open DevelopersAlready signed in? Open Studio → Developers, or use the left sidebar: Manage → Developers.
Create keyClick Create key, give it a name like Production server or Zapier, and choose Live or Test.
Copy onceCopy the secret immediately. It starts with sk_live_ or sk_test_ and is shown only once.

2 · 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

3 · 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. If you do not have a key yet, create a Studio account or open Studio → Developers.

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.

For video creation and animation, the header is strongly recommended but optional for backward compatibility. If omitted, the server returns a generated fallback in the Idempotency-Key response header and meta.idempotency_key, with meta.idempotency_key_generated set to true. New integrations should still send their own stable key because a response lost before the generated fallback arrives cannot be retried safely.

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 }.

Paid API plans

Your API key inherits the paid plan on the Studio workspace that created it. The standard ad-generation bucket is reported as images by GET /account/usage; video has its own monthly bucket.

PlanAd generations / rolling 30 daysVideo generations / rolling 30 days
Starter1005
Pro25015
Business50030
Elite1,00060

Need a higher monthly allowance, custom throughput, or a managed plan? Email members@memes.com.

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)

No public brand-audit endpoint in v1. analyze-url only extracts brand-kit profile fields; it does not create or publish brand audit reports.

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 a kit, not for running a public audit. 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