# UGC video ad, end to end

> Cast an actor, write a spoken script, shoot the take and the b-roll, caption it, and cut one finished vertical ad.

Source: https://advibly.com/docs/use-cases/ugc-video-ad



A UGC ad is a talking take intercut with product b-roll, captioned, under
thirty seconds. Advibly builds it from six calls, and the order matters:
captions go on the **finished cut**, not on the pieces.

## Open a project [#open-a-project]

```
advibly_create_project {
  brand_id,
  name: "Hydrating serum UGC ad",
  context: "Grouping the talking take, product b-roll, and final cut of the requested UGC video ad into one project."
}
  → project_id
```

Every call below carries this `project_id`. Without it the user's library
shows six loose files instead of one ad. Free.

## Cast the actor [#cast-the-actor]

```
advibly_list_actors {
  gender: "Female",
  age_range: "30-40",
  style: "Casual",
  context: "Finding a suitable talking-head actor to deliver the requested UGC script for the brand's target audience."
}
  → actor_id, image_url, preview_url
```

Stock actors speak in their own cloned voice, and the user's custom actors
speak with the voice assigned when they were created. Either way there is no
voice argument at generation time.

Show the user the `image_url` and `preview_url` before shooting. Recasting
after the take is a second charge.

## Write the script [#write-the-script]

The highest-leverage step on this page. Everything downstream renders whatever
you write here.

One talking clip is a hook. A finished ad is five beats, and each has a job:

| Beat              | Its job                                                          |
| ----------------- | ---------------------------------------------------------------- |
| 1. Hook           | Earn the next two seconds. Open on the problem, not the product. |
| 2. Problem        | Make it specific enough to be recognised.                        |
| 3. Product        | What it is and why it fixes that.                                |
| 4. Proof          | A number, a result, a before and after.                          |
| 5. Call to action | One instruction.                                                 |

Under thirty seconds, that is twenty to forty spoken words:

> "I stopped buying serums after the third one pilled under my makeup. This
> one doesn't. Three weeks, no flaking, and my foundation still sits flat.
> Link's in the bio."

Three rules decide whether it reads as a person or as an ad:

* **One idea per clip.** Three claims is three clips, which is what the
  five-beat structure is for.
* **Read it aloud before rendering.** Anything you stumble over reads as copy;
  anything you can say naturally reads as a person.
* **Write spoken words only.** Bracketed emotion tags such as `[excited]` are
  read aloud literally by the talking-actor engine.

Show the script to the user before you render it. This is the cheapest moment
to change the ad.

## Shoot the take [#shoot-the-take]

```
advibly_generate_talking_video {
  brand_id,
  project_id,
  actor_id,
  actor_source: "stock",
  script: "...",
  resolution: "720p",
  context: "Rendering the talking-actor take that delivers the approved UGC script for the brand's vertical video ad."
}
```

Cost scales with the **final audio length**, not the resolution, so a script
trimmed by a third costs a third less. Lipsync usually runs past the tool's
ten-second wait, so expect `status: pending` and a `generation_id`.

<Accordions>
  <Accordion title="Putting the same actor in a different setting">
    The default take animates the actor's portrait. To place them in a kitchen or
    a bathroom instead, generate that still first with `advibly_generate_image`,
    passing the actor's `image_url` in `reference_image_urls` and describing the
    scene. Keep the face front-facing, large, unobstructed, and the mouth closed.
    Then pass that image's URL as `start_frame_url`.
  </Accordion>

  <Accordion title="Custom actors">
    Pass `actor_source: "custom"` with an id from the `custom` entries of
    `advibly_list_actors`. A custom actor created without a voice is rejected
    rather than given a default one.
  </Accordion>
</Accordions>

## Shoot the b-roll [#shoot-the-b-roll]

Two or three product cutaways, four to six seconds each, in the same aspect
ratio as the take.

```
advibly_generate_video {
  brand_id,
  project_id,
  product_id,                 // store brands: becomes the opening frame
  prompt: "Slow push-in on the bottle as a hand lifts it off the marble
    counter, morning light, shallow depth of field.",
  aspect_ratio: "9:16",
  duration: 5,
  context: "Rendering a product cutaway to intercut with the talking take in the requested UGC video ad."
}
```

Describe **motion**, not the product, when you give a start frame. The frame
already establishes what the thing looks like; the prompt's job is camera and
action.

On a store brand `product_id` supplies the opening frame for free. Otherwise
pass a still you generated as `start_image_url`.

## Cut it together [#cut-it-together]

```
advibly_render_composition {
  brand_id,
  project_id,
  scenes: [
    { source: talkingGenerationId, trim_end_seconds: 6 },
    { source: brollGenerationId, volume: 0.2 },
    { source: talkingGenerationId, trim_start_seconds: 6 }
  ],
  music: musicGenerationId?,
  context: "Assembling the approved take and product cutaways into the finished vertical UGC ad for the brand."
}
```

Flat 0.4 credits per render, roughly one to three minutes. The result is saved
as a new video generation **and** as an editable composition; hand the user the
`edit_url` that comes back so they can fine-tune it in the visual editor.

* `trim_start_seconds` / `trim_end_seconds` are how you cut away to b-roll and
  back without re-rendering the take.
* `volume: 0.2` tucks a cutaway's own audio under the narration.
* Leave `music_volume` unset. The renderer already ducks the bed while anyone
  is speaking, and setting a low value here double-dips into silence.
* For a plain sequence of hard cuts with no audio or text work,
  `advibly_stitch_videos` does the same merge for free.

## Caption the finished cut [#caption-the-finished-cut]

```
advibly_add_subtitles {
  brand_id,
  project_id,
  video: finalGenerationId,
  preset: "glide",
  context: "Burning animated captions into the finished UGC ad so it reads correctly with sound off on social feeds."
}
```

Subtitles are billed per started minute, minimum one minute. Captioning the
take and the b-roll separately pays that minimum twice and still leaves the
cut uncaptioned, so caption **once, at the end**.

Dynamic presets (`glide`, `fusion`, `backdrop`, `whisper` and the rest) are
0.4 credits/min and animated; basic presets (`simple`, `corpo`, `beans` …) are
0.2 and static. For a social ad, a dynamic preset usually wins. The
[style sheet](https://cdn-public.advibly.com/website-assets/subtitle-captions/style-sheet.webp)
shows every one of them - look at it, or show it to the user, before choosing.

If the brand or product name gets misheard, pass `vocabulary`:

```
vocabulary: [{ word: "Advibly", replaces: ["ad vibe lee", "advibley"] }]
```

## Set the cover [#set-the-cover]

```
advibly_update_project {
  project_id,
  cover_generation_id: subtitledGenerationId,
  context: "Setting the captioned final cut as the project cover so the finished ad is what the user sees in their library."
}
```

The ad is done when the library shows the captioned cut, not shot two.

## Next [#next]

* Publish it: [Schedule a week of posts](/use-cases/schedule-a-campaign).
* Have an agent run the whole recipe: the `ugc-ads`
  [skill](/agents/skills).
