Skip to main content
POST

Overview

A Hook + Demo video opens with a short avatar reaction clip (surprise, shock, laughing…) with your hook text on top, then plays your own images or videos from the media library. Nothing is generated by an AI model: the video is assembled from the reaction clip, your text and your media, so it is the fastest format. There are no captions, voice or language settings: the price is fixed and the only words on screen are your text, drawn over the whole video. avatarId is the id of an avatar reaction, not an avatar from GET /v1/avatar/list: a library reaction or a custom reaction your team made in the dashboard. Both are listed by Get Catalog with name=reactions. Every id in media must be an image or video in your team’s library; images are shown for 5 seconds and videos play at their own length.

Reactions

GET /v1/catalog/reactions lists every reaction you can pass as avatarId: the library ones ("1" to "38", e.g. "8" Harper - Shock) with a thumbnail and the clip, then your team’s own finished reactions (source: "custom"). The text styles for textSettings.preset are in GET /v1/catalog/text-styles.

What happens next

The response’s data.status is completed: a hook demo is assembled during the request and its render starts on its own. If the timeline could not be built it is failed, the credits are refunded and no video is rendered. The video file is rendered next. Either:
  • poll GET /v1/project/{projectId} until data.video is present and data.video.status is COMPLETED, then download data.video.url; or
  • pass webhook and wait for the COMPLETED (or FAILED) call described in Webhooks:

Credits and your own keys

  • Managed teams (Hooked’s provider keys) pay 7 credits per hook demo, taken when the project is created. If the timeline cannot be built, they are refunded right away.
  • Teams on their own provider keys (BYOK) are not charged credits. They need an OpenRouter key in Settings → AI keys (the project name is generated with it). Without it the request answers 402 missing_credentials before anything is created or charged.
  • On the free plan a team can create at most 5 projects; past that the request answers 403 with limitReached: true.

Errors

Send an Idempotency-Key header to retry safely: if a request times out or answers 5xx, sending it again with the same key and body returns the first answer instead of creating (and charging) the project twice.

Project details

Follow the project until its video is ready

Webhooks

Payloads and delivery rules

List Music

Background music ids

UGC Studio

A talking avatar presenting your product

Authorizations

x-api-key
string
header
required

Headers

Idempotency-Key
string

Makes the request safe to retry. 1-255 printable ASCII characters, one per operation (your job id, or a UUID you store), reused on every retry. Within 24 hours the same key with the same body answers with the first response and the header Idempotent-Replayed: true, without running or charging again. Keys are scoped to your team and the endpoint. 5xx answers and refusals before anything ran (401, 402, 403, 409, 429) are not kept. See Idempotency.

Required string length: 1 - 255
Pattern: ^[\x20-\x7E]+$

Body

application/json
avatarId
string
required

ID of an avatar reaction (the clip that opens the video): a library reaction ("1" to "38", listed on this page) or one of your team's custom reactions. Not an ID from /v1/avatar/list. Send it as a string. An unknown ID answers 400 avatarId: Avatar "…" not found.

Required string length: 1 - 30
Example:

"8"

text
string
required

The hook text. It is drawn on top of the whole video, the reaction and the demo media, and is the only text on screen (there are no captions).

Required string length: 1 - 5000
name
string

Project name (max 100 characters). Generated from the text when omitted.

Maximum string length: 100
textSettings
object

Style of the hook text (the text is always drawn).

media
string[]

IDs of images or videos in your team's media library (max 50), played after the reaction in this order. Images are shown for 5 seconds; videos play at their own length. An ID that is not in your library answers 400 media: Media "…" not found. A media that is not COMPLETED yet (an import or upload in progress) answers 400 media: Media "<id>" is not ready (status PROCESSING).

Maximum array length: 50

Media ID from your library

aspectRatio
enum<string>
default:ratio_9_16
Available options:
ratio_9_16,
ratio_16_9,
ratio_1_1
content
object

Branding.

musicId
string

Background music ID from /v1/music/list or your own music. An unknown ID answers 400.

Maximum string length: 30
webhook
string<uri>

HTTPS URL on a public host, called when the video is ready or the project fails (max 500 characters). Requests are signed: verify the Hooked-Signature header (HMAC-SHA256 of ".") with the signing secret from Settings → Webhooks; Hooked-Event and Hooked-Delivery headers name the event and the delivery. No redirects are followed; 10 s timeout; 3 immediate attempts. See the Webhooks guide for the payload.

Maximum string length: 500
metadata
object

Any JSON object of your own (max 5 KB). Sent back in the webhook payload. The key automationId is reserved for dashboard automations and is removed.

Response

Project created. data.status is completed (assembled; the render starts on its own) or failed when the video could not be built (credits refunded, nothing is rendered). Follow the render with GET /v1/project/{projectId} or the webhook.

success
enum<boolean>
required
Available options:
true
data
object
required
message
string
required