Skip to content

Effects and catalogue

View .md

An effect is one finished, tuned generation recipe: a slug such as golden-hour-pan, the inputs it needs, the variants it can produce and a fixed price for each. The catalogue grows every week.

Terminal window
curl "https://api.moan.hot/v1/effects?type=video&limit=20" \
-H "Authorization: Bearer $MOANHOT_API_KEY"
Query Meaning
type video, image or storyboard
category One of the catalogue categories, as listed on each effect
orientation straight or gay
enabled true (default) returns only effects enabled for your account. false returns the whole catalogue
published_after Only effects published after this RFC 3339 time. Use it to sync new releases
limit, starting_after, ending_before Cursor pagination, 1 to 100 per page (default 20)

The response is a list object:

{ "object": "list", "data": [ { "id": "eff_...", "slug": "...", "...": "..." } ], "has_more": true }

To get the next page, pass the last item’s id as starting_after.

GET /effects/{slug} returns a single effect. An unknown or retired slug answers 404 effect_not_found.

Field What it is
slug The stable identifier you send to POST /generations
type video, image or storyboard
name, description Localised text: en always, plus ru, de and es where available
category, orientation Catalogue facets for your own filters
inputs[] Input slots: name (the key in inputs), kind, required, min_short_side_px
variants[] Every priced combination this effect offers (below)
blend true for two-person effects: two input photos, two people, one video
locations[] Storyboards only: key, localised name, poster_url, preview_mp4_url. Otherwise null
popularity_tier top10, trending, new or null
success_rate Share of generations that succeeded over the last 30 days
assets Sell-ready media (below)
enabled Whether your account can create it
published_at, retires_at Release date, and a retirement date when one is scheduled

A variant is one combination of axes with one fixed price. Video effects use duration, resolution, audio and prep; image effects use resolution only (1mp or 2mp); storyboards use location and resolution.

Axis Values
duration 5s, 10s, 15s for video
resolution 512p, 640p, 768p for video; 1mp, 2mp for images; 432p, 576p, 720p for storyboards
audio true adds a generated soundtrack
prep true runs frame preparation before animation, for inputs that need it
location Storyboards: the key of one of the effect’s locations[]

Each variant also has a variant_key (a stable name for the combination, beach.720p for a storyboard), price_micros and typical_seconds, the median time from request to result over the last 30 days. Send the axes, not the key, in POST /generations. A combination that is not listed answers 422 variant_unavailable.

A storyboard turns one photo into a short film: several scenes shot in one location, with the person from the photo in every scene, cut together into a single MP4. You choose the location and the resolution; each pair is its own variant with its own price.

The locations are listed on the effect itself, because each storyboard has its own and new ones arrive with catalogue releases. Read them, with their posters and previews, from GET /effects/{slug}:

Terminal window
curl "https://api.moan.hot/v1/effects/STORYBOARD_SLUG" \
-H "Authorization: Bearer $MOANHOT_API_KEY"
{
"slug": "STORYBOARD_SLUG",
"type": "storyboard",
"locations": [
{ "key": "beach", "name": { "en": "Beach" }, "poster_url": "https://...", "preview_mp4_url": "https://..." },
{ "key": "rooftop", "name": { "en": "Rooftop" }, "poster_url": "https://...", "preview_mp4_url": null }
],
"variants": [
{ "variant_key": "beach.432p", "location": "beach", "resolution": "432p", "price_micros": 1500000, "typical_seconds": 900 },
{ "variant_key": "beach.720p", "location": "beach", "resolution": "720p", "price_micros": 2500000, "typical_seconds": 900 }
]
}

To list every storyboard and its locations at once, call GET /effects?type=storyboard. A storyboard takes far longer than a video effect, often well over half an hour, so prefer a webhook to polling. See Generations for the request.

Every effect carries media ready for your own catalogue page:

  • poster_url and poster_sfw_url: still posters. Use the SFW poster on public or indexable pages.
  • preview_mp4_url, preview_webp_url: short looping previews. preview_mp4_url is always an MP4, or null when the preview exists only in another format; that preview is then in renditions[].
  • example_inputs[]: sample input photos, {position, url} (position 2 is the second photo of a blend), so you can show input next to output.
  • renditions[]: the same preview at several sizes and formats (mp4, webm, webp, jpg), with width and height.

Asset URLs are public, content-addressed and safe to cache forever. Hotlink them or copy them to your own CDN.

GET /prices returns every effect and variant price in the current price-list version, plus the next version and its effective_at when a change is scheduled. See Pricing and billing.

New effects can be enabled for your account automatically or after you review them, as you choose in the dashboard. A create for an effect you have not enabled answers 403 effect_disabled.

Subscribe a webhook endpoint to these events to keep your catalogue in sync without polling:

Event When
effect.published A new effect is live and enabled for your account. data is the full effect
effect.retired An effect is scheduled to stop. data.retires_at is at least 14 days ahead

After retires_at, creates for that slug answer 404 effect_not_found, and generations still queued for it end failed with effect_retired (never charged).

If you prefer polling, call GET /effects?published_after=<last sync time> once a day.