curl "https://api.hooked.so/v1/catalog/caption-presets" \
-H "x-api-key: your_api_key_here"
async function getCatalog(name) {
const response = await fetch(`https://api.hooked.so/v1/catalog/${name}`, {
headers: { "x-api-key": process.env.HOOKED_API_KEY },
});
const { data } = await response.json();
return data.items;
}
const styles = await getCatalog("visual-styles");
console.log(styles.map((style) => `${style.id}: ${style.name}`));
import os
import requests
def get_catalog(name):
response = requests.get(
f"https://api.hooked.so/v1/catalog/{name}",
headers={"x-api-key": os.environ["HOOKED_API_KEY"]},
)
return response.json()["data"]["items"]
games = get_catalog("games")
print([(game["id"], [clip["id"] for clip in game["clips"]]) for game in games])
{
"success": true,
"data": {
"items": [
{ "id": "default", "name": "Default" },
{ "id": "beast", "name": "Beast" },
{ "id": "tiktok", "name": "TikTok" },
{ "id": "wrap1", "name": "Wrap1" }
]
}
}
{
"success": true,
"data": {
"items": [
{
"id": "pixar",
"name": "Pixar",
"description": "3D animated style inspired by Pixar with smooth rendering and expressive characters",
"previewImageUrl": "https://assets.hooked.so/presets/pixar/1.webp",
"source": "library"
},
{
"id": "custom-cm4xb7c8d0001ef23gh45ij67",
"name": "Our brand look",
"description": null,
"previewImageUrl": "https://files.hooked.so/team/public/brand-look--fid--4e5f.webp",
"source": "custom"
}
]
}
}
{
"success": true,
"data": {
"items": [
{
"id": "model",
"name": "Video model",
"values": [
{ "id": "veo_3_fast", "name": "Veo 3.1 Fast", "durations": [4, 6, 8], "resolutions": ["720p", "1080p"], "aspectRatios": ["ratio_9_16", "ratio_16_9"] },
{ "id": "gemini_omni_flash", "name": "Gemini Omni Flash", "durations": [4, 6, 8, 10], "resolutions": ["720p"], "aspectRatios": ["ratio_9_16", "ratio_16_9"] }
]
},
{
"id": "storyTone",
"name": "Story tone",
"default": "drama",
"values": [
{ "id": "drama", "name": "Drama", "description": "Emotionally charged scenes with high personal stakes. Slower pacing, meaningful pauses, weighty dialogue." },
{ "id": "comedy", "name": "Comedy", "description": "Light and funny. Quick pacing, punchlines, exaggerated reactions, situational humor and tight jokes." }
]
},
{
"id": "presetId",
"name": "Visual style",
"default": "realistic",
"description": "Any id of GET /v1/catalog/visual-styles (your own custom-<id> included). Photorealistic styles can't be filmed with every model: excludedModels lists the ones they refuse.",
"values": [
{ "id": "realistic", "excludedModels": ["seedance_2_0", "seedance_2_0_fast", "seedance_2_0_mini"] }
]
},
{ "id": "durationSeconds", "name": "Duration (seconds)", "min": 10, "max": 120, "default": 30 },
{ "id": "characterIds", "name": "Characters", "description": "Ids of GET /v1/character/list.", "max": 6 }
]
}
}
{
"success": false,
"message": "Catalog \"fonts\" not found. Valid names are: caption-presets, text-styles, visual-styles, motion-styles, games, reactions, video-models, image-models, cinematic, camera-moves, gestures, voice-presets, accents"
}
Resources
Get Catalog
The fixed values the create endpoints take: caption styles, visual styles, games, reactions, AI models, Cinematic options and more
GET
/
v1
/
catalog
/
{name}
curl "https://api.hooked.so/v1/catalog/caption-presets" \
-H "x-api-key: your_api_key_here"
async function getCatalog(name) {
const response = await fetch(`https://api.hooked.so/v1/catalog/${name}`, {
headers: { "x-api-key": process.env.HOOKED_API_KEY },
});
const { data } = await response.json();
return data.items;
}
const styles = await getCatalog("visual-styles");
console.log(styles.map((style) => `${style.id}: ${style.name}`));
import os
import requests
def get_catalog(name):
response = requests.get(
f"https://api.hooked.so/v1/catalog/{name}",
headers={"x-api-key": os.environ["HOOKED_API_KEY"]},
)
return response.json()["data"]["items"]
games = get_catalog("games")
print([(game["id"], [clip["id"] for clip in game["clips"]]) for game in games])
{
"success": true,
"data": {
"items": [
{ "id": "default", "name": "Default" },
{ "id": "beast", "name": "Beast" },
{ "id": "tiktok", "name": "TikTok" },
{ "id": "wrap1", "name": "Wrap1" }
]
}
}
{
"success": true,
"data": {
"items": [
{
"id": "pixar",
"name": "Pixar",
"description": "3D animated style inspired by Pixar with smooth rendering and expressive characters",
"previewImageUrl": "https://assets.hooked.so/presets/pixar/1.webp",
"source": "library"
},
{
"id": "custom-cm4xb7c8d0001ef23gh45ij67",
"name": "Our brand look",
"description": null,
"previewImageUrl": "https://files.hooked.so/team/public/brand-look--fid--4e5f.webp",
"source": "custom"
}
]
}
}
{
"success": true,
"data": {
"items": [
{
"id": "model",
"name": "Video model",
"values": [
{ "id": "veo_3_fast", "name": "Veo 3.1 Fast", "durations": [4, 6, 8], "resolutions": ["720p", "1080p"], "aspectRatios": ["ratio_9_16", "ratio_16_9"] },
{ "id": "gemini_omni_flash", "name": "Gemini Omni Flash", "durations": [4, 6, 8, 10], "resolutions": ["720p"], "aspectRatios": ["ratio_9_16", "ratio_16_9"] }
]
},
{
"id": "storyTone",
"name": "Story tone",
"default": "drama",
"values": [
{ "id": "drama", "name": "Drama", "description": "Emotionally charged scenes with high personal stakes. Slower pacing, meaningful pauses, weighty dialogue." },
{ "id": "comedy", "name": "Comedy", "description": "Light and funny. Quick pacing, punchlines, exaggerated reactions, situational humor and tight jokes." }
]
},
{
"id": "presetId",
"name": "Visual style",
"default": "realistic",
"description": "Any id of GET /v1/catalog/visual-styles (your own custom-<id> included). Photorealistic styles can't be filmed with every model: excludedModels lists the ones they refuse.",
"values": [
{ "id": "realistic", "excludedModels": ["seedance_2_0", "seedance_2_0_fast", "seedance_2_0_mini"] }
]
},
{ "id": "durationSeconds", "name": "Duration (seconds)", "min": 10, "max": 120, "default": 30 },
{ "id": "characterIds", "name": "Characters", "description": "Ids of GET /v1/character/list.", "max": 6 }
]
}
}
{
"success": false,
"message": "Catalog \"fonts\" not found. Valid names are: caption-presets, text-styles, visual-styles, motion-styles, games, reactions, video-models, image-models, cinematic, camera-moves, gestures, voice-presets, accents"
}
Overview
Many create fields take a value from a fixed list: a caption style, a visual style, a game, an AI model. This endpoint returns those lists, read from the same registries the create endpoints validate against. Everyid a catalog returns is accepted where the table below says, and a value that is not in the list answers 400 with the allowed values. When Hooked adds a style or a model, it shows up here; you never have to copy a list from the docs.
Each item has an id (what you send) and a name (the label the dashboard shows), plus a few fields that depend on the catalog: a preview image for visual styles, the clips of a game, the media types and sound of a model. Catalogs your team can add to (visual-styles with your custom styles as custom-<id>, reactions with your own reactions) include your team’s entries after the library ones, and only finished ones. The call is free and safe to repeat; caching the static catalogs on your side for a day is fine.
name | Field it feeds | Endpoints |
|---|---|---|
caption-presets | caption.preset | Every endpoint that burns captions |
text-styles | textSettings.preset | Hook Demo |
visual-styles | presetSettings.preset, presetId, style | Narrated formats with ai-images / ai-videos, Cinematic, Generate Image |
motion-styles | presetSettings.motionStyleId | motion-graphics media type |
games | gameplaySettings.selectedGame, and selectedVideo from its clips | gameplay media type |
reactions | avatarId | Hook Demo |
video-models | presetSettings.aiModel, model | ai-videos media type, Generate Video (durations, resolutions, aspectRatios, startFrame, endFrame, maxReferenceImages and makesSound say what each model takes) |
image-models | presetSettings.aiModel, model | ai-images media type, Generate Image (maxReferenceImages) |
cinematic | model, imageModel, storyTone, presetId, durationSeconds, characterIds, language, aspectRatio | Cinematic (one item per field) |
camera-moves | videoStyle.cameras | Talking Avatar, UGC Studio (ugcStudioFormats says which formats allow each move) |
gestures | videoStyle.gestures (send the id: the library’s own words) | Talking Avatar, UGC Studio |
voice-presets | videoStyle.voice, hostVoice | Talking Avatar, UGC Studio, Podcast Interview |
accents | videoStyle.accent, accent | Talking Avatar, UGC Studio, Podcast Interview |
The cinematic catalog
cinematic has one item per field of Create Cinematic Video that takes a fixed value. An item has the accepted values (each model with its durations, resolutions and aspectRatios), or min / max bounds, and the default used when you leave the field out. The presetId item lists the photorealistic styles together with the models that refuse them (excludedModels); any other visual style works with every model.
curl "https://api.hooked.so/v1/catalog/caption-presets" \
-H "x-api-key: your_api_key_here"
async function getCatalog(name) {
const response = await fetch(`https://api.hooked.so/v1/catalog/${name}`, {
headers: { "x-api-key": process.env.HOOKED_API_KEY },
});
const { data } = await response.json();
return data.items;
}
const styles = await getCatalog("visual-styles");
console.log(styles.map((style) => `${style.id}: ${style.name}`));
import os
import requests
def get_catalog(name):
response = requests.get(
f"https://api.hooked.so/v1/catalog/{name}",
headers={"x-api-key": os.environ["HOOKED_API_KEY"]},
)
return response.json()["data"]["items"]
games = get_catalog("games")
print([(game["id"], [clip["id"] for clip in game["clips"]]) for game in games])
{
"success": true,
"data": {
"items": [
{ "id": "default", "name": "Default" },
{ "id": "beast", "name": "Beast" },
{ "id": "tiktok", "name": "TikTok" },
{ "id": "wrap1", "name": "Wrap1" }
]
}
}
{
"success": true,
"data": {
"items": [
{
"id": "pixar",
"name": "Pixar",
"description": "3D animated style inspired by Pixar with smooth rendering and expressive characters",
"previewImageUrl": "https://assets.hooked.so/presets/pixar/1.webp",
"source": "library"
},
{
"id": "custom-cm4xb7c8d0001ef23gh45ij67",
"name": "Our brand look",
"description": null,
"previewImageUrl": "https://files.hooked.so/team/public/brand-look--fid--4e5f.webp",
"source": "custom"
}
]
}
}
{
"success": true,
"data": {
"items": [
{
"id": "model",
"name": "Video model",
"values": [
{ "id": "veo_3_fast", "name": "Veo 3.1 Fast", "durations": [4, 6, 8], "resolutions": ["720p", "1080p"], "aspectRatios": ["ratio_9_16", "ratio_16_9"] },
{ "id": "gemini_omni_flash", "name": "Gemini Omni Flash", "durations": [4, 6, 8, 10], "resolutions": ["720p"], "aspectRatios": ["ratio_9_16", "ratio_16_9"] }
]
},
{
"id": "storyTone",
"name": "Story tone",
"default": "drama",
"values": [
{ "id": "drama", "name": "Drama", "description": "Emotionally charged scenes with high personal stakes. Slower pacing, meaningful pauses, weighty dialogue." },
{ "id": "comedy", "name": "Comedy", "description": "Light and funny. Quick pacing, punchlines, exaggerated reactions, situational humor and tight jokes." }
]
},
{
"id": "presetId",
"name": "Visual style",
"default": "realistic",
"description": "Any id of GET /v1/catalog/visual-styles (your own custom-<id> included). Photorealistic styles can't be filmed with every model: excludedModels lists the ones they refuse.",
"values": [
{ "id": "realistic", "excludedModels": ["seedance_2_0", "seedance_2_0_fast", "seedance_2_0_mini"] }
]
},
{ "id": "durationSeconds", "name": "Duration (seconds)", "min": 10, "max": 120, "default": 30 },
{ "id": "characterIds", "name": "Characters", "description": "Ids of GET /v1/character/list.", "max": 6 }
]
}
}
{
"success": false,
"message": "Catalog \"fonts\" not found. Valid names are: caption-presets, text-styles, visual-styles, motion-styles, games, reactions, video-models, image-models, cinematic, camera-moves, gestures, voice-presets, accents"
}
Errors
| Status | When |
|---|---|
| 401 | Missing or invalid API key (code: "not_authenticated") |
| 403 | The team does not have the Hooked app product (code: "entitlement_required") |
| 404 | Unknown catalog name (the message lists the valid ones), or cinematic on a platform without Cinematic videos (code: "feature_not_available") |
Authorizations
Path Parameters
Which catalog.
Available options:
caption-presets, text-styles, visual-styles, motion-styles, games, reactions, video-models, image-models, cinematic, camera-moves, gestures, voice-presets, accents