# ChatGPT
> Adding Advibly to ChatGPT as a connector.
Source: https://advibly.com/docs/agents/clients/chatgpt
### Add the connector [#add-the-connector]
In ChatGPT, go to **Settings → Connectors → Add**, and give it:
```
https://advibly.com/mcp
```
### Sign in [#sign-in]
ChatGPT opens Advibly's OAuth flow. Approve it.
### Enable it in a conversation [#enable-it-in-a-conversation]
Turn the connector on for the chat you want to use it in.
### Verify [#verify]
Ask: “Use Advibly to list my brands and credit balance.” Setup is complete when
both calls return account data without asking for an API key.
## Notes [#notes]
ChatGPT's connector flow omits a scope that some OAuth servers require;
Advibly's registration endpoint handles that, so no special configuration is
needed on your side.
As with any client, tool calls act as your Advibly account. Listing data is
free; generation spends credits. Ask ChatGPT to state the planned billable
calls before a multi-step production.
If the connector is enabled but no tools appear, start a new chat after
authorising it. For authentication errors, reconnect it and repeat OAuth.
---
# Claude Code
> Adding Advibly to Claude Code from the terminal.
Source: https://advibly.com/docs/agents/clients/claude-code
Add the remote server:
```bash
claude mcp add --transport http advibly https://advibly.com/mcp
```
Then, inside Claude Code:
```
/mcp
```
and sign in when prompted. The tools are available from the next message.
## Verify the connection [#verify-the-connection]
Ask Claude Code to “Use Advibly to list my brands and credit balance.” Setup is
complete when it returns account data without asking for an API key. This check
does not start a generation.
## Why this one is worth having [#why-this-one-is-worth-having]
Claude Code can hold a whole production in its head: read your brand, open a
project, generate a storyboard, render every shot, assemble the result and
schedule the post - without you switching windows.
The [skills](/agents/skills) are written for exactly this: `npx skills add`
installs a full production recipe that drives these tools.
If `/mcp` shows Advibly but a call returns `401`, reconnect the server and
repeat the browser sign-in. If the tool arguments differ from a docs example,
have Claude Code refresh the live tool list.
---
# Claude
> Adding Advibly to Claude as a connector.
Source: https://advibly.com/docs/agents/clients/claude
Claude connects to Advibly as a **custom connector**, authorised in the browser.
### Open connector settings [#open-connector-settings]
In Claude, go to **Settings → Connectors → Add custom connector**.
### Give it the URL [#give-it-the-url]
```
https://advibly.com/mcp
```
Leave everything else at its default. There is no API key field to fill in.
### Authorise [#authorise]
Claude opens an Advibly sign-in. Approve it, and the connector's tools appear
in new conversations.
### Verify [#verify]
Start a new conversation, enable the connector, and ask: “List my Advibly
brands.” Setup is complete when Claude returns the account's brands without
asking for an API key.
## First message [#first-message]
> List my Advibly brands, then make three static ad concepts for the first one.
Claude should resolve a real `brand_id`, explain the planned billable calls,
generate three images, and collect any result that is still pending.
## Notes [#notes]
* Tool calls spend your Advibly credits. Ask for the cost first if you are
unsure: `advibly_check_credits` shows your balance.
* For anything multi-step, ask Claude to open a project so the output is
grouped - see [Use cases](/use-cases/ugc-video-ad).
* Claude also has [skills](/agents/skills) for whole productions, like a
finished UGC ad or an animated explainer.
* If the connector disappears or returns `401`, remove it, add it again, and
repeat OAuth. See [Connection failures](/agents/mcp#connection-failures).
---
# Codex
> Adding Advibly to Codex.
Source: https://advibly.com/docs/agents/clients/codex
Add the server to your Codex configuration:
```toml
[mcp_servers.advibly]
url = "https://advibly.com/mcp"
```
Then sign in:
```bash
codex mcp login advibly
```
Restart the Codex session after login so it discovers the server's current
tools.
## Verify the connection [#verify-the-connection]
Ask Codex: “Use Advibly to list my brands and credit balance.” Setup is complete
when both calls return account data without asking for an API key.
For a multi-step production, ask Codex to create or reuse a project, pass its
`project_id` on every generation, and report the planned billable calls before
starting. The worked [use cases](/use-cases/launch-campaign-image-set) provide
complete execution paths.
If login succeeds but no Advibly tools appear, start a new session. If a call
returns `401`, run `codex mcp login advibly` again.
---
# Cursor
> Adding Advibly to Cursor.
Source: https://advibly.com/docs/agents/clients/cursor
Add Advibly to your MCP configuration:
```json
{
"mcpServers": {
"advibly": {
"url": "https://advibly.com/mcp"
}
}
}
```
Cursor will prompt you to authorise when the server is first used. Sign in with
your Advibly account.
## Verify the connection [#verify-the-connection]
Open a new agent conversation and ask: “Use Advibly to list my brands and
credit balance.” Setup is complete when Cursor returns account data without
asking for an API key.
The same JSON works for any client that reads an `mcpServers` block, including
Claude Desktop.
If the tools do not appear, reload the Cursor window after OAuth. If a call
returns `401`, remove the saved connection, add it again, and repeat sign-in.
---
# Other clients
> OpenClaw, Hermes, and anything else that speaks MCP.
Source: https://advibly.com/docs/agents/clients/other
Advibly is a standard Streamable HTTP MCP server with OAuth, so any compliant
client works. The two pieces of information every client needs:
| | |
| -------- | ------------------------------------------------------- |
| **URL** | `https://advibly.com/mcp` |
| **Auth** | OAuth 2.1 with dynamic client registration. No API key. |
## OpenClaw [#openclaw]
```bash
openclaw mcp set advibly '{"url":"https://advibly.com/mcp","transport":"streamable-http","auth":"oauth"}'
openclaw mcp login advibly
```
## Hermes and others [#hermes-and-others]
Point the client at the URL and let it run the OAuth flow. If your client
supports dynamic client registration - most do - there is nothing to configure
beyond the URL.
The connection is complete when `tools/list` includes `advibly_list_brands` and
calling it returns the signed-in account's brands. Use
`advibly_check_credits` as the second read-only verification call.
## Writing your own client [#writing-your-own-client]
The endpoint speaks the current MCP specification over Streamable HTTP and is
stateless, so it works with standard SDK clients without special handling.
Discovery starts at `/.well-known/mcp.json`.
The client must preserve the OAuth token, send it as a bearer token, and accept
the tool schemas returned by `tools/list` rather than hard-coding arguments.
Generation calls may return either a completed result or a pending
`generation_id`; see [Generation statuses](/reference/generation-statuses).
If you would rather not write a client at all, the [`advibly`
CLI](/cli) is one: it logs in through the same chain and turns `tools/list`
into subcommands.
---
# VS Code
> Adding Advibly to VS Code.
Source: https://advibly.com/docs/agents/clients/vscode
VS Code uses a `servers` block and wants the transport named explicitly:
```json
{
"servers": {
"advibly": {
"type": "http",
"url": "https://advibly.com/mcp"
}
}
}
```
Authorise in the browser when prompted. No API key is involved.
## Verify the connection [#verify-the-connection]
Start a new agent chat and ask: “Use Advibly to list my brands and credit
balance.” Setup is complete when VS Code returns account data without an
authentication error.
If the server is configured but the tools are absent, reload the VS Code window
after OAuth. Confirm the transport remains `http`; Advibly does not use stdio or
the legacy SSE transport.
---
# Connect over MCP
> One endpoint, OAuth, no API key - how to point any MCP client at Advibly.
Source: https://advibly.com/docs/agents/mcp
Advibly's MCP server is at:
```
https://advibly.com/mcp
```
Transport is **Streamable HTTP**. Authentication is **OAuth 2.1** with dynamic
client registration and PKCE. There is no API key to create, copy or leak - you
sign in in a browser once and the client holds the token.
This page is the client-independent setup. If the client has its own page under
[Clients](/agents/clients/claude), follow that page first and return here for
the connection contract and first calls.
## Adding it [#adding-it]
```bash
claude mcp add --transport http advibly https://advibly.com/mcp
```
Then run `/mcp` inside Claude Code and sign in when prompted.
```json
{
"mcpServers": {
"advibly": {
"url": "https://advibly.com/mcp"
}
}
}
```
```json
{
"servers": {
"advibly": {
"type": "http",
"url": "https://advibly.com/mcp"
}
}
}
```
```toml
[mcp_servers.advibly]
url = "https://advibly.com/mcp"
```
Then:
```bash
codex mcp login advibly
```
```bash
openclaw mcp set advibly '{"url":"https://advibly.com/mcp","transport":"streamable-http","auth":"oauth"}'
openclaw mcp login advibly
```
For ChatGPT, add it as a connector rather than a config file - see
[ChatGPT](/agents/clients/chatgpt). The Clients section contains the complete
setup for every supported client.
## How the auth works [#how-the-auth-works]
You do not need to know this to use it, but it helps when something goes wrong:
1. The client calls the endpoint unauthenticated and gets a `401`.
2. The `401` points at `/.well-known/oauth-protected-resource/mcp`.
3. That points at Advibly's authorization server metadata, which registers the
client dynamically and then hands off to the sign-in flow.
4. The client gets a token and uses it as a bearer on every call.
Every tool call acts as the signed-in Advibly account, and generation tools
spend that account's credits.
## First calls [#first-calls]
Verify the connection with `advibly_list_brands`. It proves that tool discovery,
OAuth, and account access all work without spending credits:
```json
{
"name": "advibly_list_brands",
"arguments": {
"context": "Finding the available brand contexts and identifiers before starting the user's requested creative production workflow through Advibly."
}
}
```
which gives you the `brand_id` every generation tool needs.
The setup is complete when the call returns the user's brands—or an empty list
for a new account—without an authentication error. Then call
`advibly_check_credits` before planning billable work.
## Onboarding a brand without the app [#onboarding-a-brand-without-the-app]
If the account has no brand yet, a new user still never has to open a browser
tab. `advibly_onboard_brand` runs the real onboarding from a URL and returns a
brand that behaves exactly like one created in the app.
```
advibly_onboard_brand {
url: "acme.com",
context: "Creating the account's primary brand context from its public website before producing the requested campaign assets."
}
```
It is idempotent: re-running it with a URL the account already has returns the
existing brand rather than creating a second one. On the account's *first*
brand it also returns plan options, because that is the point at which the
[brand limit](/reference/limits) starts to matter.
After onboarding, keep the returned `brand_id`; do not guess it from the brand
name or URL.
## Connection failures [#connection-failures]
| Symptom | Next action |
| ----------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ |
| `401` or sign-in loop | Remove the stale connection in the client, add the endpoint again, and complete OAuth in the same browser session. |
| Server cannot be reached | Confirm the URL is exactly `https://advibly.com/mcp` and the transport is Streamable HTTP. |
| Tools appear but calls reject `context` | Send a 15–25 word, third-person reason for the call; see [Tool reference](/agents/tools#the-call-contract). |
| Tool names or arguments differ from this manual | Refresh `tools/list`; the live schema is authoritative. |
## Discovery endpoints [#discovery-endpoints]
| Path | What it is |
| ----------------------- | -------------------------------------- |
| `/.well-known/mcp.json` | Endpoint, transport and authentication |
| `/agents.md` | When to use Advibly, in markdown |
| `/llms.txt` | Product overview |
| `/docs/llms.txt` | This manual, indexed |
---
# Agent skills
> Whole productions as installable recipes - UGC ads, explainers, claymation, restyles.
Source: https://advibly.com/docs/agents/skills
A skill is a production recipe an agent installs once and then runs. Where a
tool makes one clip, a skill orchestrates the MCP calls for a complete ad:
casting, script, storyboard, every shot, voiceover, score, and assembly.
Use a skill when the deliverable needs a repeatable production process. Use a
single MCP tool when the requested output is one image, clip, voiceover, or
other isolated asset.
## The catalogue [#the-catalogue]
| Skill | What it produces |
| -------------------------------------------------- | -------------------------------------------------------------------------------- |
| **UGC Video Ads** (`ugc-ads`) | One brand plus an angle becomes a finished multi-shot UGC video ad. |
| **Static Ads** (`static-ads`) | One brand becomes a batch of static ad concepts across fifteen proven layouts. |
| **Animated Explainer Videos** (`explainer-videos`) | One topic becomes a narrated animated explainer, in any of ten visual styles. |
| **Vox Explainer Ads** (`vox-explainer`) | One claim becomes a narrated paper-collage explainer, cut like a real short. |
| **Claymation Ads** (`claymation-ad`) | One product becomes a warm, narrated stop-motion clay ad. |
| **Pixar-Style Ads** (`pixar-style-ad`) | A brand and product become a warm, original feature-film 3D animated ad. |
| **Collage Motion Ads** (`collage-motion`) | A reference decoded into an editable spec, then animated assemble-from-empty. |
| **Stickman Animation Ads** (`stickman-animation`) | A brand idea becomes a visually dense stick-figure video, directed clip by clip. |
| **Video Restyle** (`video-restyle`) | One finished video becomes eleven completely different visual worlds. |
Each has its own page with the full recipe at
[advibly.com/skills](https://advibly.com/skills).
## Installing [#installing]
```bash
npx skills add https://github.com/advibly/skills -s ugc-ads
```
Download the `.skill` bundle from the skill's page and drop it into
**Claude → Settings → Skills**.
```bash
git clone https://github.com/advibly/skills.git
cp -R skills/ugc-ads ~/.claude/skills/
```
Replace `ugc-ads` with the catalogue slug for the production you want. Install
one skill first; add more only when the request needs a different production
path.
## What a skill needs [#what-a-skill-needs]
A skill drives the [MCP tools](/agents/tools), so the agent must be connected
to Advibly first - see [Connect over MCP](/agents/mcp). It spends credits like
any other generation. The agent should check the balance before a full
production and report the planned calls before spending credits.
## Verify and run [#verify-and-run]
After installation, start a new agent session and ask it to list the installed
Advibly skills. Then invoke the skill with one brand and one concrete outcome,
for example:
> Use the UGC ads skill to make a 20-second vertical launch ad for Acme's new
> bottle. Show me the production plan and expected billable calls before you
> generate anything.
The skill is working when the agent follows its recipe, resolves a real
`brand_id`, opens or reuses a project, and pauses at any approval gate the
recipe defines. A production is complete only when the final render is
`completed`, shared with the user, and set as the project cover.
A skill supplies the process, not account access. Missing brands, credits, or
social connections still have to be resolved through the MCP tools.
## Discovery [#discovery]
Agents can find the catalogue at
`/.well-known/agent-skills/index.json`, which follows the Agent Skills
Discovery convention.
---
# Tool reference
> Every tool on the Advibly MCP server, grouped by what it is for.
Source: https://advibly.com/docs/agents/tools
Use this page to choose a capability. Before calling it, read that tool's live
schema from MCP `tools/list`; the schema is authoritative for arguments,
defaults, models, constraints, and cost notes.
All tools act as the signed-in Advibly account. Anything that calls a model
spends that account's credits; read-only and organisational calls are free.
## The call contract [#the-call-contract]
Every tool schema includes a required `context` string. It must describe, in
15-25 words and in third person, why that call supports the user's goal. Do not
put credentials, personal data, or other secrets in it. MCP clients should
read this requirement from `tools/list`; the Advibly CLI fills it automatically.
`brand_id` is **required** on every generation tool. It decides where the
generation is filed, not whether brand styling is applied - that is a separate
`on_brand` argument.
For any workflow with several generated parts, create or reuse a project and
pass its `project_id` to every generation. The run is organised only when every
intermediate and final belongs to that project.
The live list is always authoritative: `tools/list` on the server, or `advibly
tools` from the CLI. This page groups and explains them.
## Choose the tool [#choose-the-tool]
| Need | Use |
| ------------------------------------------ | --------------------------------------------------- |
| Inspect the account before work | `advibly_list_brands`, `advibly_check_credits` |
| Create a brand from its public site | `advibly_onboard_brand` |
| Anchor an ad to a real product or asset | `advibly_get_products`, `advibly_get_assets` |
| Make one media asset | A matching `advibly_generate_*` tool |
| Assemble clips, narration, music, and text | `advibly_render_composition` |
| Join clips with hard cuts only | `advibly_stitch_videos` |
| Understand or cut an existing video | `advibly_analyze_video` |
| Collect a pipeline's outputs | `advibly_list_generations` filtered by `project_id` |
| Publish or schedule finished media | `advibly_social_create_post` |
## Credits [#credits]
| Tool | What it does |
| ----------------------- | -------------------------------------------- |
| `advibly_check_credits` | Current balance. |
| `advibly_buy_credits` | Available credit packs, with checkout links. |
## Brands [#brands]
| Tool | What it does |
| ------------------------------- | -------------------------------------------------------------- |
| `advibly_list_brands` | Every brand with its id and `brand_type`. **Start here.** |
| `advibly_get_brand` | One brand's identity and research brief. |
| `advibly_get_brand_dossier` | The full sourced knowledge base for a brand. |
| `advibly_update_brand` | Change identity fields. |
| `advibly_update_brand_document` | Write a new version of the brief or dossier. |
| `advibly_view_brandkit` | The rendered brand style sheet. |
| `advibly_onboard_brand` | Create the user's own brand from a URL, end to end. |
| `advibly_quick_brand` | A ready-to-generate brand from a URL, skipping onboarding. |
| `advibly_list_quick_brands` | List those. |
## Products and assets [#products-and-assets]
| Tool | What it does |
| --------------------------- | ------------------------------------------------------------------- |
| `advibly_get_products` | The brand's product catalog. A product id becomes the ad's subject. |
| `advibly_get_assets` | The brand's asset library. |
| `advibly_create_upload_url` | A presigned `PUT` target. Preferred for anything of size. |
| `advibly_upload_asset` | Register an uploaded file as an asset. |
## Generation [#generation]
| Tool | What it does |
| -------------------------------- | ------------------------------- |
| `advibly_generate_image` | A static image. |
| `advibly_generate_video` | A video clip, with audio. |
| `advibly_generate_talking_video` | An actor delivering a script. |
| `advibly_generate_carousel` | A multi-slide deck. |
| `advibly_export_carousel_pdf` | That deck as a PDF. |
| `advibly_generate_voiceover` | Text to speech. |
| `advibly_generate_music` | A generated track. |
| `advibly_list_actors` | Stock actors and brand avatars. |
## Video post-production [#video-post-production]
| Tool | What it does |
| ---------------------------- | ----------------------------------------------------------------- |
| `advibly_render_composition` | Assemble a complete video in one call. |
| `advibly_stitch_videos` | Join 2-12 clips with hard cuts. Free. |
| `advibly_add_subtitles` | Burn in captions, 150+ languages, optional translation. |
| `advibly_analyze_video` | Analyse a video: ad breakdown, shots, transcript, cut plan. Free. |
## Jobs and projects [#jobs-and-projects]
| Tool | What it does |
| -------------------------- | --------------------------------- |
| `advibly_get_generation` | Status and results. Poll this. |
| `advibly_list_generations` | The library, filterable. |
| `advibly_create_project` | Open a project before a pipeline. |
| `advibly_list_projects` | List them. |
| `advibly_update_project` | Rename, or set the cover. |
## Publishing [#publishing]
| Tool | What it does |
| ---------------------------------- | ------------------------------------------- |
| `advibly_social_list_accounts` | Connected accounts and their `profile_id`s. |
| `advibly_social_create_post` | Publish or schedule. |
| `advibly_social_update_post` | Edit a scheduled post. |
| `advibly_social_delete_post` | Delete one. |
| `advibly_social_list_posts` | List posts, optionally with performance. |
| `advibly_social_get_post` | One post. |
| `advibly_social_get_profile_stats` | Account-level stats. |
| `advibly_social_arm_dm_automation` | Arm a comment-to-DM flow on a post. |
## Generation results [#generation-results]
Generation calls wait briefly before returning:
* `completed`: use the returned URL. Do not make a redundant status call.
* `pending` or `processing`: keep the `generation_id`. The in-chat widget keeps
polling; call `advibly_get_generation` only when a downstream tool needs the
finished URL.
* `failed` or `rejected`: the credits are refunded. Use the returned reason to
change the next attempt.
See [Generation statuses](/reference/generation-statuses).
---
# Command reference
> The built-in commands, plus how every MCP tool becomes one.
Source: https://advibly.com/docs/cli/commands
## Built-in commands [#built-in-commands]
| Command | What it does |
| ---------------------------------- | ------------------------------------------------------------- |
| `advibly login` | Browser OAuth. Tokens go to `~/.config/advibly`. |
| `advibly logout` | Sign out of this server. `--all` for every profile. |
| `advibly whoami` | Who you are signed in as. |
| `advibly tools` | Every tool the server currently exposes, grouped. |
| `advibly tools ` | One tool's full schema. `--refresh` re-reads from the server. |
| `advibly call ''` | Call a tool directly with a raw argument object. |
| `advibly upload ` | Local file into the brand's asset library. |
| `advibly download ` | Result files to disk. `-o `. |
| `advibly config set\|unset\|list` | Default arguments. See [Configuration](/cli/configuration). |
| `advibly version` | Version. |
## Generated commands [#generated-commands]
Everything else is generated from the server's tool list:
```bash
advibly generate-image --prompt "..." --brand-id
advibly list-generations --status completed
advibly social-create-post --caption "..." --profile-ids
```
The mapping is mechanical:
* `advibly_generate_image` → `advibly generate-image`
* `brand_id` → `--brand-id`
* enums become choices, numbers are validated
* arrays are repeatable, or passed once as a JSON array
* objects are passed as JSON
`advibly --help` lists whatever the server exposes today.
Use `advibly tools ` when writing or repairing a script. The returned
schema—not this page—is the completion check for argument names, required
fields, enums, and current defaults.
## Passing raw arguments [#passing-raw-arguments]
When a flag is awkward, pass the whole object:
```bash
advibly generate-image --args '{"brand_id":"...","prompt":"..."}'
advibly generate-image --args-file ./brief.json
cat brief.json | advibly generate-image --args-file -
```
Explicit flags override anything in `--args`.
Anything without a generated command can still be called:
```bash
advibly call advibly_check_credits '{}' --json
```
The CLI supplies the required MCP `context` argument automatically. Pass the
task arguments only; scripts do not need to manufacture analytics context.
## Waiting for generations [#waiting-for-generations]
Generation commands poll until the job is terminal rather than returning a
pending id.
| Flag | Effect |
| --------------------- | ------------------------------------------ |
| `--no-follow` | Return immediately with the generation id. |
| `--timeout ` | Cap the wait. Default 1800. |
| `--json` | Machine-readable output. |
## Exit codes [#exit-codes]
| Code | Meaning |
| ---- | ---------------------------------------------- |
| `0` | Success. |
| `1` | Tool error, or a failed / rejected generation. |
| `2` | Usage error. |
| `3` | Login required. |
These make the CLI usable in CI without parsing output.
For automation, require both exit code `0` and the expected output field. A
successful command with the wrong brand or project is still the wrong result.
---
# Configuration
> Default arguments, profiles, environment variables and where state lives.
Source: https://advibly.com/docs/cli/configuration
## Default arguments [#default-arguments]
`advibly config` stores defaults applied to any command whose schema has that
property, when you do not pass the flag:
```bash
advibly config set brand_id
advibly config set project_id
advibly config list
advibly config unset project_id
```
Setting `brand_id` once is the single biggest quality-of-life change, since
almost every generation command takes it.
Defaults are profile-scoped. Verify `advibly whoami` and `advibly config list`
before a batch that can spend credits; together they identify the account and
arguments the batch will use.
## Environment [#environment]
| Variable | Effect |
| -------------------- | ---------------------------------------------------- |
| `ADVIBLY_SERVER` | MCP endpoint. Defaults to `https://advibly.com/mcp`. |
| `ADVIBLY_CONFIG_DIR` | Relocates the whole state directory. Useful in CI. |
| `ADVIBLY_DEBUG` | `1` prints stack traces for unexpected errors. |
## Profiles [#profiles]
`--server ` overrides the endpoint for one command. A bare host gets
`/mcp` appended automatically.
Each endpoint keeps its **own profile** - tokens, OAuth client and defaults -
and its own tool cache, keyed by host. Switching servers never mixes
credentials, which is what makes pointing the CLI at a staging deployment safe.
## State on disk [#state-on-disk]
Everything lives under `~/.config/advibly`:
* tokens, owner-readable only
* one profile per server host
* a tool-list cache per account, under `cache/`
`advibly logout --all` clears every profile.
Treat the state directory as credentials. Keep it out of source control and do
not copy one user's profile into shared CI storage.
## In CI [#in-ci]
```bash
export ADVIBLY_CONFIG_DIR=/tmp/advibly
export ADVIBLY_SERVER=https://advibly.com/mcp
advibly generate-image --args-file ./brief.json --json --timeout 900
```
Check the [exit code](/cli/commands#exit-codes) rather than parsing the output.
Use an isolated `ADVIBLY_CONFIG_DIR` per CI identity so concurrent jobs cannot
overwrite one another's profile or defaults.
---
# The Advibly CLI
> Advibly from a terminal - install, log in, and make something.
Source: https://advibly.com/docs/cli
`advibly` is Advibly from a shell script. Every command is a tool of the
[MCP server](/agents/mcp), so anything an agent can do, you can do from a
terminal: brands, assets, image, video and audio generation, projects, social
publishing.
Use the CLI when a workflow starts with local files, must write results to
disk, or belongs in a script. Use MCP directly when the work is being planned
and reviewed inside an agent conversation.
## Install [#install]
```bash
npm i -g advibly
```
Or run it without installing:
```bash
npx advibly
```
Needs Node 20 or later, and an Advibly account.
## Connect [#connect]
```bash
advibly login
```
This opens a browser for the same OAuth flow Claude Code and Cursor use. Tokens
are stored in `~/.config/advibly` with owner-only permissions. There is no API
key to manage.
```bash
advibly whoami # confirm who you are signed in as
advibly logout # sign out of this server (--all for every profile)
```
The connection is ready when `advibly whoami` prints the intended account and
`advibly list-brands` returns its brands.
## Make something [#make-something]
```bash
advibly list-brands
advibly config set brand_id
advibly generate-image --prompt "..." --aspect-ratio 4:5
```
Setting `brand_id` as a default once saves passing it to every subsequent
command. See [Configuration](/cli/configuration).
The generation command waits for a terminal result by default. A successful
run ends with exit code `0` and prints the completed result; use `--json` when a
script will consume it.
## Move files [#move-files]
The two things a CLI can do that an agent cannot:
```bash
advibly upload ./product.png # local file -> brand asset library
advibly download -o ./out # results -> disk
```
## It is an MCP client, not a second API [#it-is-an-mcp-client-not-a-second-api]
The CLI speaks to `https://advibly.com/mcp` and turns the server's `tools/list`
into subcommands. `advibly_generate_image` becomes `advibly generate-image`,
and each argument becomes a flag (`brand_id` → `--brand-id`).
The practical consequence: **a new tool becomes a new command with no CLI
upgrade.** The list is refreshed on login and with `advibly tools --refresh`.
## Credits [#credits]
Generation commands spend the connected account's credits. Read-only and
organisational MCP tools do not.
```bash
advibly check-credits
advibly buy-credits
```
Before a batch, check the balance once and estimate the number of billable
generation calls. A failed or rejected generation is refunded automatically.
---
# Advibly MCP documentation
> Connect an AI agent to Advibly, discover its tools, and run complete creative production workflows over MCP.
Source: https://advibly.com/docs
Advibly is a remote Model Context Protocol server for producing branded images,
videos, audio, carousels, and social campaigns. Connect once, authorise with
OAuth, and your AI client can work with the brands, assets, credits, and
projects attached to your Advibly account.
```
https://advibly.com/mcp
```
The server uses **Streamable HTTP** and **OAuth 2.1**. It does not require an
API key.
## Choose the shortest path [#choose-the-shortest-path]
| Goal | Start here |
| ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| Connect an agent for the first time | [Connect over MCP](/agents/mcp) |
| Configure a specific client | [Claude](/agents/clients/claude), [ChatGPT](/agents/clients/chatgpt), [Claude Code](/agents/clients/claude-code), [Cursor](/agents/clients/cursor), [VS Code](/agents/clients/vscode), or [Codex](/agents/clients/codex) |
| Choose or inspect a tool | [Tool reference](/agents/tools), then the live `tools/list` schema |
| Complete a production job | [Use cases](/use-cases/launch-campaign-image-set) |
| Run a production recipe | [Agent skills](/agents/skills) |
| Automate from a terminal | [CLI quickstart](/cli) |
## The MCP workflow [#the-mcp-workflow]
### Connect and authorise [#connect-and-authorise]
Point a Streamable HTTP client at `https://advibly.com/mcp`. The client opens
Advibly's OAuth flow and stores the resulting token.
### Discover the live tools [#discover-the-live-tools]
Use MCP `tools/list`. Tool schemas are the source of truth for arguments,
defaults, supported models, and current capabilities.
### Resolve account context [#resolve-account-context]
Start with `advibly_list_brands` and `advibly_check_credits`. Most generation
tools need a real `brand_id` returned by the server.
### Generate and collect [#generate-and-collect]
Generation calls wait briefly. A fast job returns `completed` with its result;
a slower job returns `pending` with a `generation_id`. Call
`advibly_get_generation` only when a later step needs the finished URL.
The connection is ready when `advibly_list_brands` returns the account's real
brand ids. A production is complete when every requested deliverable is
`completed`, collected for the user, and—when it used a project—the strongest
final is set as the project cover.
## What the server exposes [#what-the-server-exposes]
| Capability | MCP tools cover |
| --------------- | ---------------------------------------------------------------------- |
| Brand context | Brand onboarding, research, identity, products, and assets |
| Generation | Images, video, talking actors, carousels, voiceover, and music |
| Post-production | Video analysis, stitching, subtitles, and composition renders |
| Organisation | Generations and projects |
| Distribution | Social publishing, scheduling, analytics, and comment-to-DM automation |
## Machine-readable documentation [#machine-readable-documentation]
Every page has a markdown twin. Append `.md` to a docs URL, or request it with
`Accept: text/markdown`.
* [`/docs/llms.txt`](/llms.txt) indexes every MCP docs page.
* [`/docs/llms-full.txt`](/llms-full.txt) contains the complete MCP manual.
* [`advibly.com/agents.md`](https://advibly.com/agents.md) is the short product
brief for an agent before its first call.
---
# Credit costs
> How a price is arrived at, and roughly what things cost.
Source: https://advibly.com/docs/reference/credit-costs
## The formula [#the-formula]
One credit is one US dollar. A generation's price is the underlying compute
cost with a fixed markup applied, rounded up - to the nearest 0.01 credit for
images and 0.1 for video.
Nothing else affects it: there is no per-seat charge, no minimum, and no
difference between a credit granted by a subscription and one bought in a pack.
For planning, count **billable calls**, not final deliverables. A five-shot ad
can include five stills, five clips, voiceover, music, and one composition even
though the user receives one video.
## Rough figures [#rough-figures]
Everyday defaults, to calibrate expectations:
| Generation | Approx. cost |
| -------------------------------------- | ---------------------------------- |
| One image, cheap model, 1K | \~0.09 credits |
| One image, GPT Image family, medium | a few hundredths to \~0.05 credits |
| One image, high quality | several times the medium price |
| 8-second video, 720p, everyday model | \~1.9 credits |
| 8-second video, 1080p or premium model | several times that |
| Talking actor, 15 seconds, 720p | \~2 credits |
| Voiceover, 30 seconds | a fraction of a credit |
| Composition render | 0.4 credits |
## What drives the price [#what-drives-the-price]
The two dominant factors, and they multiply. Halving the duration halves the
price; dropping 1080p to 720p typically does more than that.
Quality tiers are not linear. On supported GPT Image models the highest tiers
are several times the medium price for the same dimensions.
Most image models add a small per-reference charge. Three references on a
cheap model can cost more than the base image.
A base per-minute rate, doubled for dynamic caption styles, doubled again
above 1080p, with a further per-minute charge if translated.
## The authoritative number [#the-authoritative-number]
The MCP tool schema and the client's approval prompt describe the billable
operation before it runs. Use `advibly_check_credits` before a multi-call
workflow, and `advibly_buy_credits` to retrieve current packs and checkout
links. This page is for rough planning; model IDs and prices can change.
Before a multi-call workflow:
1. Resolve the exact number of image, video, audio, and render calls.
2. Read the live schema for each selected model and setting.
3. Call `advibly_check_credits`.
4. Tell the user which planned steps spend credits before starting the batch.
The estimate is ready only when it covers every proof, variant, retry budget,
and final render—not just the finished deliverable.
---
# Generation statuses
> The lifecycle of a generation, and what to do when one does not complete.
Source: https://advibly.com/docs/reference/generation-statuses
Every generation - image, video, talking actor, carousel, audio, composition -
moves through the same states.
```
pending → processing → completed | failed | rejected
```
| Status | Meaning | Credits |
| ------------ | ------------------------------- | ------------ |
| `pending` | Queued, not started. | Reserved |
| `processing` | The model is working. | Reserved |
| `completed` | Done. Results available. | Spent |
| `failed` | The model or pipeline errored. | **Refunded** |
| `rejected` | Declined by content moderation. | **Refunded** |
## Handle the first response [#handle-the-first-response]
Generation tools wait briefly before returning:
| First response | Action |
| ------------------------------------------------ | ---------------------------------------------------------------------------------------------- |
| `completed` with result URLs | Use the result. A status call adds no value. |
| `pending` or `processing` with a `generation_id` | Keep the id. Call `advibly_get_generation` only when a downstream step needs the finished URL. |
| `failed` | Read the reason, change the unstable setting if failures repeat, and retry. |
| `rejected` | Change the subject, framing, or prompt before trying again. |
The in-chat widget continues polling pending work for display. When an agent
needs the result programmatically, `advibly_get_generation` waits by default
and accepts `wait` and `timeout_seconds`. The CLI follows jobs unless you pass
`--no-follow`.
Do not treat a long `processing` as a failure and re-submit. You will be
charged for both. Video generations legitimately take minutes, and heavy image
settings occasionally take several.
## When something fails [#when-something-fails]
`failed` usually means a transient error on the model provider's side.
Re-submitting the same request is the right response, and costs nothing extra
because the first attempt was refunded.
If the same request fails repeatedly, the settings are the likely cause -
typically an unusual dimension or duration combination. Falling back to a
default model and size will tell you which.
The retry is complete only when the replacement reaches `completed`; a new
`generation_id` is not evidence that the problem is fixed.
## When something is rejected [#when-something-is-rejected]
`rejected` is content moderation. It is stricter than you would expect on some
ordinary commercial subjects - swimwear and skin-heavy product categories in
particular.
The usual fix is to stage the product without a person in the frame. See
[Troubleshooting](/reference/troubleshooting).
---
# MCP limits
> Account entitlements and server-side limits that affect MCP tool calls.
Source: https://advibly.com/docs/reference/limits
## Brands [#brands]
| Plan | Brands |
| --------------- | --------- |
| No subscription | 1 |
| Create | 1 |
| Publish | 5 |
| Studio | Unlimited |
Quick brands created through `advibly_quick_brand` do not count against the
regular brand limit.
Before onboarding another regular brand, call `advibly_list_brands`. If the
plan is at its limit, reuse the existing brand or resolve the entitlement
instead of retrying the same call.
## Social accounts [#social-accounts]
`advibly_social_list_accounts` can return up to ten connected social accounts
for a brand. Publishing tools require the account's publishing entitlement.
## Generations [#generations]
There is no cap on how many generations you may run. The limit is your credit
balance.
## Video analysis [#video-analysis]
`advibly_analyze_video` is free of credits but rate-limited, and direct HTTPS
video input is capped at roughly 18 MiB per video. Larger sources should be
hosted somewhere the analyser can stream them.
## Uploads [#uploads]
| Input path | Limit or constraint |
| ---------------------- | --------------------------------------------------------------------------- |
| Presigned image upload | Up to 25 MiB |
| Presigned video upload | Up to 200 MiB |
| Inline `data_base64` | Small images only; hard cap 8 MiB and practical client limits may be lower |
| Public `source_url` | The server must be able to fetch the URL without interactive authentication |
For a local file, use `advibly_create_upload_url`, upload the exact bytes with
HTTP `PUT`, then register its returned `upload_key` with
`advibly_upload_asset`. The signed `size_bytes` must match the uploaded body.
## Credits [#credits]
No expiry, no reset, no cap on how many you may hold.
Use `advibly_check_credits` for the live balance. A low balance limits billable
generation but does not block read-only account, brand, project, or library
calls.
---
# Models and parameters
> How MCP clients discover current model IDs, defaults, constraints, and cost-driving parameters.
Source: https://advibly.com/docs/reference/models
Model availability changes faster than a static documentation page. Before
setting `model`, read the generation tool's input schema from MCP `tools/list`.
Its enum, description, default, compatible modes, resolutions, durations, and
other limits are authoritative.
Omit `model` to use Advibly's current default. Pin a model only when the
workflow depends on a capability or visual character unique to that model.
## Select a model only when necessary [#select-a-model-only-when-necessary]
1. Read the target tool's live schema.
2. Omit `model` for the current default unless the job requires a named
capability such as edit mode, a specific duration, or a particular output
resolution.
3. Validate the whole combination—model, mode, duration, aspect ratio,
resolution, and references—against the same schema.
4. Render a cheap proof before raising quality, resolution, duration, or the
number of outputs.
Selection is complete when every requested parameter is accepted by one model
without relying on clamping or an undocumented fallback.
## Image generation [#image-generation]
`advibly_generate_image` exposes the current image-model enum. The main
cost-driving parameters are:
| Parameter | Effect |
| ---------------------- | --------------------------------------------------------------------- |
| `resolution` | Higher output dimensions cost more. |
| `quality` | Model-specific quality tier; upper tiers can cost several times more. |
| `num_images` | Generates and bills for each requested image. |
| `reference_image_urls` | Switches supported models into reference/edit mode. |
| `on_brand` | Attaches brand identity references when true. |
Use `medium` quality while exploring and raise it only for a final asset when
the selected model supports that value.
## Video generation [#video-generation]
`advibly_generate_video` exposes each current video model plus the allowed
`mode`, `duration`, `resolution`, and media-reference fields. Video is normally
priced by output duration and capability tier; resolution and model choice can
multiply the result.
Different models support different combinations. Do not copy a resolution or
mode from one model to another without checking the live schema.
When a video setting fails repeatedly, return to the default model and one of
its documented combinations, then reintroduce one override at a time.
## Talking actors and audio [#talking-actors-and-audio]
* `advibly_generate_talking_video` lists its current engines, actors, supported
resolutions, and duration rules.
* `advibly_generate_voiceover` and `advibly_generate_music` expose their current
voices, models, and length constraints through their schemas.
* `advibly_list_actors` returns the actor IDs accepted by talking-video calls.
## Fixed and utility operations [#fixed-and-utility-operations]
Operations such as video analysis, stitching, subtitles, and composition
rendering have their own schemas and pricing behavior. Use the tool description
returned by `tools/list`, then check [Credit costs](/reference/credit-costs)
before a large workflow.
---
# Troubleshooting
> The problems that actually come up, and what to do about them.
Source: https://advibly.com/docs/reference/troubleshooting
Start with the exact structured error returned by the tool. Preserve its
`error` code, message, and relevant id; those decide the branch below. Change
one variable per retry so the result identifies the cause.
## A generation was rejected [#a-generation-was-rejected]
Content moderation declined it, and your credits were refunded.
The filters are stricter than the subject matter suggests. Swimwear, underwear
and skin-heavy product categories trip them routinely, even for ordinary
catalogue photography.
**What works**: stage the product without a person in the frame - flat-lay,
on a hanger, in an empty room. You usually get the shot you wanted, and it is
often a better product ad anyway.
## A generation failed [#a-generation-failed]
The model provider errored. Credits were refunded; re-submitting is free and
usually works.
If it fails repeatedly, change one thing at a time - first the model, then the
size or duration. Unusual dimension and duration combinations are the most
common cause.
## It has been processing for a long time [#it-has-been-processing-for-a-long-time]
Video legitimately takes minutes. Heavy image settings - the highest quality
tier, a large size, and several brand references together - occasionally take
five minutes or more.
Re-submitting does not cancel the first attempt, and you pay for both. If you
are past five minutes on an image, re-submitting at `medium` quality is usually
faster than continuing to wait.
## The output ignored my brand [#the-output-ignored-my-brand]
Two different things get confused here:
* `brand_id` decides where the generation is **filed**.
* `on_brand` decides whether brand **styling** is applied.
A generation with brand styling off is still filed under the brand. Check the
`on_brand` argument sent to the MCP tool.
If styling is on and the output still looks wrong, the brand itself is probably
wrong. Call `advibly_get_brand` to inspect its identity and
`advibly_view_brandkit` to inspect the rendered brand kit.
## The text in my image is gibberish [#the-text-in-my-image-is-gibberish]
Write the literal words in quotes inside the `prompt`, spell the brand name
exactly, and say where the text belongs in the composition.
## My agent cannot connect [#my-agent-cannot-connect]
Work through it in this order:
1. Call `advibly_check_credits` with a valid `context` - it proves tool access
without starting a generation.
2. If it 401s, sign in again from the client. Tokens expire.
3. Confirm the URL is exactly `https://advibly.com/mcp`.
4. Confirm the transport is Streamable HTTP, not SSE or stdio.
If discovery works but the call rejects `context`, send a 15–25 word,
third-person explanation of how the call supports the user's goal. Do not put
credentials or personal data in it.
## An agent says a brand does not exist [#an-agent-says-a-brand-does-not-exist]
Call `advibly_list_brands` and use an id from the response. Brand ids are not
guessable, and an agent that invented one will get this error.
The same rule applies to products, projects, profiles, posts, actors, assets,
and generations: resolve ids from a list or create response in the signed-in
account; never infer them from names.
## The account has insufficient credits [#the-account-has-insufficient-credits]
Call `advibly_check_credits` to confirm the balance, then
`advibly_buy_credits` to retrieve current packs and checkout links. Share the
link and stop the billable branch. Credits apply after payment; resume from the
first generation that did not run rather than repeating completed work.
## A local upload returns `403` [#a-local-upload-returns-403]
Create a new presigned URL using the file's exact MIME type and byte length,
then `PUT` the unchanged raw bytes. A different body size invalidates the
signature. After the upload succeeds, call `advibly_upload_asset` with the
returned `upload_key`; the `PUT` alone does not add the file to the library.
## A post did not publish [#a-post-did-not-publish]
Call `advibly_social_list_accounts` for the brand. If the target profile is
missing or disconnected, its network authorisation must be renewed before MCP
can publish to it. A failed post can be retried without recreating it.
## Still stuck [#still-stuck]
[Advibly support](https://advibly.com/support).
---
# Cut a long video into clips
> Rank the moments in a webinar, podcast, or long ad, cut each into its own vertical clip, caption it, and schedule the set.
Source: https://advibly.com/docs/use-cases/clip-a-long-video
One recording, ten posts. The analyser finds the moments worth cutting, and
`advibly_render_composition` does the cutting with per-scene trims.
The whole read side is free. You pay 0.4 credits per clip cut, plus captions.
## Rank the moments [#rank-the-moments]
```
advibly_analyze_video {
video_url: "https://www.youtube.com/watch?v=...",
format: "moments",
question: "Find the strongest standalone clips for vertical social - a claim, a story, or a contrarian take that needs no setup.",
context: "Ranking the highlights of the user's long recording so the strongest standalone moments can be cut into social clips."
}
→ analysis_id, moments[]: start, end, why
```
`moments` is the format built for exactly this: ranked highlights for clipping
and re-hooking. The `question` steers what counts as strong.
| Source | Limit |
| ------------ | --------------------------------------- |
| YouTube URL | Passed straight through, no size limit. |
| `gs://` URI | Passed straight through. |
| Direct https | Up to 18 MB. |
| Generation | `generation_id` instead of `video_url`. |
A two-hour webinar is fine. The analyser reads the transcript, then zooms into
the frames that matter rather than sampling the whole file.
Ask follow-ups with `follow_up_of: analysis_id` and a `question`. The video is
already in that analysis's context, which makes every extra question far
cheaper than a second full pass.
## Verify the cut points before spending [#verify-the-cut-points-before-spending]
Timestamps are the model's estimate, and a clip that starts mid-word is a
wasted render. Confirm the boundaries of each moment you intend to cut:
```
advibly_analyze_video {
follow_up_of: analysis_id,
question: "For the moment at 18:42, give the exact second the speaker starts that sentence and the exact second they finish it.",
thinking: "high",
context: "Confirming exact sentence boundaries for a chosen highlight so the cut clip starts and ends cleanly."
}
```
`thinking: "high"` is worth it for counting and exact-timestamp questions.
## Open a project [#open-a-project]
```
advibly_create_project {
brand_id,
name: "Q3 webinar clips",
context: "Grouping every clip cut from the user's long recording into one project in their library."
}
→ project_id
```
Ten clips and ten captioned versions is twenty files. One tile is better.
## Cut each moment [#cut-each-moment]
One render per clip, one scene, trimmed:
```
advibly_render_composition {
brand_id,
project_id,
scenes: [
{
source: "https://.../webinar.mp4",
trim_start_seconds: 1122.0,
trim_end_seconds: 1166.5
}
],
texts: [
{ content: "The part nobody tells you", start_seconds: 0, duration_seconds: 2.5, position: "top", size: "lg" }
],
context: "Cutting the confirmed highlight out of the long recording as a standalone social clip with its hook card."
}
```
Flat 0.4 credits, one to three minutes. `source` is a generation id or a
direct https video URL.
Every scene is **scaled to fill the canvas**. A 16:9 recording cut for a
vertical feed gets cropped to the centre, so a speaker sitting off to one side
can end up half out of frame. Cut one clip first and look at it before running
the other nine.
The result is saved as a new video generation and as an editable composition.
Hand the user its `edit_url` when the framing needs a human eye.
## Caption every clip [#caption-every-clip]
```
advibly_add_subtitles {
brand_id,
project_id,
video: clipGenerationId,
preset: "glide",
context: "Burning captions into the cut clip so it reads with sound off in a social feed."
}
```
Billed per started minute, minimum one minute, so a 40-second clip and a
55-second clip cost the same. Dynamic presets are 0.4 credits/min and
animated, basic presets 0.2 and static; the
[style sheet](https://cdn-public.advibly.com/website-assets/subtitle-captions/style-sheet.webp)
shows all of them.
Add `translation_language` to caption in a different language than the audio
(+0.4 credits/min), and `vocabulary` for names the transcriber mishears.
## Stitch, when the ask is a compilation [#stitch-when-the-ask-is-a-compilation]
```
advibly_stitch_videos {
brand_id,
project_id,
clips: [clip1, clip2, clip3],
context: "Joining the selected clips into one compilation reel in the order the user approved."
}
```
Free, 2 to 12 clips, hard cuts in the order given. The output takes the
**first** clip's aspect ratio and mismatched clips get letterboxed, so put a
correctly-shaped clip first.
## Next [#next]
* Send the set out: [Schedule a week of posts](/use-cases/schedule-a-campaign).
* Read the source as an ad instead of a recording:
[Recreate an ad you like](/use-cases/recreate-an-ad).
---
# Launch campaign image set
> Produce one coherent set of on-brand statics - resolve the product, prove one prompt, fan it out across every placement.
Source: https://advibly.com/docs/use-cases/launch-campaign-image-set
A campaign set is not five unrelated images. It is **one prompt system**
rendered at several aspect ratios, so the placements look like they came from
the same shoot.
The cost of getting this wrong is paid at the end, in a set you have to redo.
So render one **proof** first, and only fan out once the proof is right.
## Resolve the subject [#resolve-the-subject]
```
advibly_list_brands {
context: "Finding the brand and its identifier before producing the requested launch campaign image set for the user."
}
→ brand_id, brand_type
```
`brand_type` decides where the subject comes from:
| `brand_type` | The subject of the ad |
| ------------------------- | ----------------------------------------------------------------------- |
| `ecom_store` | A catalog product. Call `advibly_get_products` and hold a `product_id`. |
| `website` | The offer itself. Describe the scene; there is no product photo. |
| `app_ios` / `app_android` | App-store screenshots, already in `advibly_get_assets`. |
Passing `product_id` attaches that product's hero photo as a reference, so the
generated image features the real product rather than a plausible-looking
invention. On a store brand, use it.
## Open a project [#open-a-project]
A set is a pipeline, and a pipeline that skips this scatters a dozen loose
files across the user's library.
```
advibly_create_project {
brand_id,
name: "Spring launch statics",
context: "Grouping every image of the requested launch campaign set under one project in the user's library."
}
→ project_id
```
Pass that `project_id` on every generation call below. Free.
## Write the prompt system once [#write-the-prompt-system-once]
Every image in the set shares a scene, a lighting setup, a palette behaviour
and a type treatment. Write that paragraph once and change only the framing
per placement.
```
advibly_generate_image {
brand_id,
project_id,
product_id?,
prompt: "Photorealistic overhead flat-lay on warm sand-coloured linen, soft
late-afternoon window light from the left, real fabric texture and visible
grain. The product sits centre-right, label facing camera. Headline
\"Made for mornings\" in the brand display face, upper-left, generous
margin. No watermark, no stray text, no unrelated logos.",
quality: "medium",
context: "Rendering one proof image for the requested launch set before committing the full set of placements."
}
```
Three rules that decide whether the set is usable:
* **Put on-image text in quotes, exactly as it should read**, spell the brand
name out, and say where it sits. Anything described loosely comes back
loosely.
* **Leave hex codes and font names out when `on_brand` is on.** The brand kit
is attached as a reference automatically, and restating it in the prompt
fights the reference. Describe the scene instead.
* **Ask for real texture and candid framing** rather than quality words like
`8K` or `cinematic`, which push the model toward stock-photo gloss.
`brand_id` decides where the generation is **filed**. `on_brand` (default
true) decides whether brand **styling** is applied. They are separate
arguments, and a set that came back off-brand is usually `on_brand: false`.
## Check the proof [#check-the-proof]
The proof is good when the product is the real product, the headline reads
character-for-character as written, and the composition has room for the text
at every ratio you are about to request.
If the text came back wrong, fix the prompt rather than the model. If the
product came back wrong, you are missing `product_id`.
## Vary the argument, not the aesthetics [#vary-the-argument-not-the-aesthetics]
A set is five **angles**, not twelve variations of one. The look stays fixed;
the line it makes changes:
| Angle | The line it makes |
| ---------- | -------------------------------- |
| Problem | The thing that is annoying today |
| Product | What it is, plainly |
| Offer | The launch price or the deadline |
| Proof | A number, a review, a result |
| Comparison | Against the obvious alternative |
Change the headline and the staging per angle. Keep the scene, the light and
the type treatment from the proof.
## Fan out the placements [#fan-out-the-placements]
Generate each placement rather than cropping one image. A 9:16 built as 9:16
puts the headline where it belongs; a 1:1 cropped to 9:16 puts it off-screen.
One call per placement, changing `aspect_ratio` and nothing else:
| `aspect_ratio` | Placement |
| -------------- | ------------------------------ |
| `1:1` | Feed square, marketplace |
| `4:5` | Instagram and Facebook feed |
| `9:16` | Stories, Reels, TikTok, Shorts |
| `16:9` | YouTube, display, website hero |
| `3:2` / `21:9` | Email header, wide banner |
`num_images` renders up to four variants of the **same** call and bills for
each, which is the right tool for picking between takes at one ratio, and the
wrong one for covering several ratios.
## Raise quality for the finals [#raise-quality-for-the-finals]
Explore at `medium`. Raise only the placements that ship.
| `quality` | When |
| --------------- | ----------------------------------------------------- |
| `low` | Thumbnails and layout tests. |
| `medium` | The default. Every proof, and most finals. |
| `high` | A hero placement. Roughly four times `medium`. |
| `xhigh` / `max` | A print or billboard crop. Each step is another \~4x. |
`resolution` moves independently: `1K` for a proof, `2K` (the default) for
social, `4K` when the asset gets cropped or printed.
Story and Reels placements put platform UI over the top and bottom of the
frame. Ask for generous margins there, and check nothing that matters sits
under the chrome.
`high` and above, with several brand references attached, occasionally runs
past five minutes. Re-submitting does not cancel the first render and you pay
for both - see [Generation statuses](/reference/generation-statuses).
## Collect the set [#collect-the-set]
Fast renders return `status: completed` with their URLs inline. Slower ones
return `status: pending` and a `generation_id`; call `advibly_get_generation`
for those, and only when you need the URL for a next step.
```
advibly_list_generations {
brand_id,
project_id,
type: ["image"],
limit: 24,
context: "Collecting every completed image from the requested launch set so the user receives the finished placements together."
}
```
`type` is a list, and `limit` defaults to 4 - a six-placement set comes back
truncated without it.
Set the strongest placement as the project cover, so the library shows the
campaign rather than a cropped variant:
```
advibly_update_project {
project_id,
cover_generation_id,
context: "Setting the hero placement as the project cover so the finished campaign set is identifiable in the library."
}
```
## Next [#next]
* Schedule the set: [Schedule a week of posts](/use-cases/schedule-a-campaign).
* Turn a still into motion: [UGC video ad, end to end](/use-cases/ugc-video-ad).
* Hand the whole job to an agent: the `static-ads`
[skill](/agents/skills) runs this across fifteen proven layouts.
---
# Recreate an ad you like
> Tear a reference ad down with the analyser, then rebuild it shot by shot on your own product using two reference images.
Source: https://advibly.com/docs/use-cases/recreate-an-ad
Someone sends a link to an ad that works and asks for the same thing with
their product in it. The temptation is to watch it, describe it in prose, and
generate from the description.
That loses exactly the details you were trying to keep. The reliable technique
is a **teardown** followed by **two references** per shot.
## Tear the reference down [#tear-the-reference-down]
`advibly_analyze_video` is free and reads the real file, not a summary of it.
```
advibly_analyze_video {
video_url: "https://www.youtube.com/watch?v=...",
format: "ad_breakdown",
context: "Reading the structure of the reference ad the user wants recreated before rebuilding it with their own product."
}
→ analysis_id, hook, cta, claims, on_screen_text, transcript, shots, segments
```
`ad_breakdown` returns the creative teardown: the hook, the CTA, the claims,
every piece of on-screen text, a verbatim timestamped transcript, a shot list,
and `segments` - a 3-10 second cut plan that is your shot-by-shot build order.
| Source | How to pass it |
| --------------------- | --------------------------------------- |
| YouTube | The watch URL, directly. |
| An Advibly generation | `generation_id` instead of `video_url`. |
| A direct file | Public https URL, up to 18 MB. |
| Cloud Storage | A `gs://` URI. |
A share page (Google Drive, Dropbox) is not a file. Download it and upload it
via `advibly_create_upload_url` first.
To ask more about the same ad, pass `follow_up_of: analysis_id` with just a
`question`. The video is already in context, which makes it the cheapest way
to keep digging.
## Verify the cut points [#verify-the-cut-points]
Timestamps in the teardown are the model's estimate. Check them against the
real duration before you build anything around them. For a frame-precise look
at one window:
```
advibly_analyze_video {
video_url,
clip_start_seconds: 2.4,
clip_end_seconds: 5.0,
fps: 6,
detail: "high",
question: "Exactly when does the product first enter frame, and what text is on screen?",
context: "Confirming the precise cut point and on-screen text of the reference ad's opening shot before rebuilding it."
}
```
`clip_*` and `fps` switch the analyser into static mode, which samples the
window at a fixed rate instead of navigating agentically.
## Decide what transfers [#decide-what-transfers]
Structure transfers between brands. Aesthetics usually do not: the reference's
palette belongs to a different company, and carrying it over makes the ad look
like theirs rather than the user's.
| Keep | Drop |
| --------------------------- | ---------------------- |
| The argument it makes | Their colours |
| The beat order and pacing | Their type |
| The product's role in frame | Their voice and claims |
The exception is the shot-level composition, which you keep deliberately in
the next step because that is what the reference was for.
## Open a project [#open-a-project]
```
advibly_create_project {
brand_id,
name: "Competitor spot, our version",
context: "Grouping every rebuilt shot and the final assembly of the requested ad recreation into one project."
}
→ project_id
```
## Rebuild each shot: two references, never prose [#rebuild-each-shot-two-references-never-prose]
This is the step everything else depends on. For each segment in the cut plan,
generate the opening still with **both** the source frame and your product as
reference images:
```
advibly_generate_image {
brand_id,
project_id,
reference_image_urls: [sourceFrameUrl, productPhotoUrl],
prompt: "Recreate the composition, framing, lighting and colour grade of
image 1, with the product from image 2 in place of its product. Keep the
camera angle and the position in frame identical.",
context: "Rebuilding the reference ad's opening composition with the brand's own product as the subject."
}
```
The source frame carries the composition, the grade and the crop. The product
photo carries the thing you are actually selling. Describing either one in
words is where the resemblance goes.
Get the source frames by extracting stills from the reference, or by asking
the analyser for the exact moments and pulling those frames.
A recreation is a new creative execution on your own product, not a copy of
someone's footage. Rebuild the structure - hook, pacing, shot grammar, CTA -
and put your own product, brand and claims in it.
## Animate each still [#animate-each-still]
```
advibly_generate_video {
brand_id,
project_id,
start_image_url: rebuiltStillUrl,
prompt: "Slow handheld drift right, the subject stays centred.",
duration: 4,
aspect_ratio: "9:16",
context: "Animating the rebuilt opening still to match the reference ad's camera move for that segment."
}
```
Match each clip's `duration` to its segment length in the cut plan. Describe
the camera move only; the still already decided the look.
## Re-voice it [#re-voice-it]
Rewrite the transcript for your product, keeping the beat structure and the
line lengths, then:
```
advibly_generate_voiceover {
brand_id,
project_id,
text: "...",
voice: "eve",
context: "Generating the rewritten narration for the recreated ad so the timing matches the reference ad's beat structure."
}
```
0.03 credits per 1000 characters. Write to time at roughly 2.5 words a second.
With the default `xai` provider the text takes inline `[pause]`, `[sigh]`,
`[laugh]` and wrapping `` / `` tags; with `cartesia` those tags
are read aloud, so leave them out there.
## Assemble to the cut plan [#assemble-to-the-cut-plan]
```
advibly_render_composition {
brand_id,
project_id,
scenes: [ { source: clip1 }, { source: clip2 }, { source: clip3 } ],
voiceovers: [
{ source: voGenerationId, start_seconds: 0 }
],
music: musicGenerationId?,
texts: [
{ content: "60% off, today only", start_seconds: 8.5, position: "bottom", size: "lg" }
],
context: "Assembling the rebuilt shots, rewritten narration and on-screen text into the finished recreated ad."
}
```
One voiceover segment per scene, each started at that scene's timeline offset,
keeps narration locked to the visuals. A single full-length track also works
when the pacing already matches.
## The other route: restyle the clip itself [#the-other-route-restyle-the-clip-itself]
When the ask is "the same ad, different look" rather than "the same ad, our
product", skip the rebuild entirely:
```
advibly_generate_video {
brand_id,
model: "gemini-omni-flash-1.1",
source_video_url: sourceClipUrl,
prompt: "Restyle as hand-painted gouache animation, warm palette.",
context: "Restyling the user's existing clip into the requested visual world while keeping its timing intact."
}
```
Video-to-video output inherits the source's length and aspect ratio, so
`duration` and `aspect_ratio` are ignored. It needs an actual video file; hand
it a still and the call is refused rather than silently wasting four minutes.
## Next [#next]
* Give the recreation captions and a schedule:
[UGC video ad](/use-cases/ugc-video-ad),
[Schedule a week of posts](/use-cases/schedule-a-campaign).
---
# Schedule a week of posts
> Turn finished generations into a scheduled week across connected accounts, with per-platform overrides and comment-to-DM armed before publish.
Source: https://advibly.com/docs/use-cases/schedule-a-campaign
Publishing is where an agent quietly does damage: a post going out now instead
of Tuesday, or landing on the wrong account. Two habits prevent both. Resolve
the targets explicitly, and schedule rather than publish while the user is
still reviewing.
## Resolve the targets [#resolve-the-targets]
```
advibly_social_list_accounts {
brand_id,
context: "Listing the brand's connected social accounts before scheduling the approved campaign posts to the right profiles."
}
→ accounts[]: profile_id, platform, handle, status, placements
```
Target `profile_ids` explicitly. Omitting both `profile_ids` and
`target_platforms` publishes to **every** connected account on the brand,
which is rarely what a week's plan means.
If the brand holds several accounts per network, they are grouped into
**account sets**, and one post cannot span two sets. Send a separate post per
set. Naming a platform instead of `profile_ids` targets the primary set only.
## Attach media by generation id [#attach-media-by-generation-id]
```
advibly_social_create_post {
brand_id,
caption: "Three weeks, no pilling. Our serum, now in the 50ml size.",
generation_ids: [imageGenerationId],
profile_ids: [instagramProfileId, tiktokProfileId],
scheduled_at: "2026-10-01T09:00:00Z",
context: "Scheduling the approved campaign image and caption on the selected profiles at the user's requested publishing time."
}
→ post_id, status, postproxy_post_id
```
`generation_ids` resolves the Advibly media automatically, which is more
reliable than pasting URLs. `media_urls` exists for anything that did not come
from Advibly.
Scheduling mode is decided by which arguments you send:
| Arguments | What happens |
| ---------------------------------- | ---------------------------------------------- |
| Neither `scheduled_at` nor `queue` | Publishes **now**. |
| `scheduled_at` (ISO 8601) | Scheduled for that instant. |
| `queue: true` | Dropped into the brand's queue, slot assigned. |
| `draft: true` | Saved, not published. |
While the user is still approving copy, `draft: true` or a `scheduled_at`
well in the future are both safe. Publishing now is not reversible by
deleting the post.
## Per-platform overrides [#per-platform-overrides]
One call covers the week's cross-posting; `platform_configurations` handles
where the networks disagree.
```
platform_configurations: {
youtube: { title: "Three weeks, no pilling", privacy_status: "public" },
instagram: { caption: "...", format: "reel" },
linkedin: { organization_id: "" },
facebook: { page_id: "" }
}
```
| Network | The rule that bites |
| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Facebook | **Always** needs `page_id`. It cannot post to a personal profile. |
| LinkedIn | A company page needs `organization_id`. Without it the post goes to the personal profile. |
| YouTube | A custom `cover_url` is invalid on Shorts and is dropped automatically for vertical clips of three minutes or less. Long-form keeps it, and the channel must be verified. |
Both ids come from the `placements` on `advibly_social_list_accounts`.
## Arm comment-to-DM in the same call [#arm-comment-to-dm-in-the-same-call]
A trigger is keyed by the post id, which exists from the moment of scheduling.
So arming a scheduled post makes the automation live the minute it publishes,
and there is no window where the caption asks for a comment nothing answers.
```
advibly_social_create_post {
brand_id,
caption: "Comment GUIDE and I'll DM you the full routine 👇",
generation_ids: [...],
scheduled_at: "2026-10-01T09:00:00Z",
dm_automation: {
keyword: "GUIDE",
thing: "morning routine guide",
link: "https://example.com/guide",
link_title: "Get the guide",
flow: "guide-drop"
},
context: "Scheduling the campaign post and arming its comment-to-DM automation so the caption's call to action works from publish."
}
```
* `guide-drop` (the default) sends a DM with a button, checks whether the
person follows the posting account, then delivers the link card.
`link-drop` puts the link in the first DM with no follow gate.
* `once_per_user` is `per_post` by default; `ever` and `never` are the other
two.
* Instagram only, and the caption has to tell people to comment the keyword.
The automation is what delivers the link; the caption is what triggers it.
On a post that already exists, `advibly_social_arm_dm_automation` takes the
same fields plus `post_id`. Drafts have no post id, so `dm_automation` and
`draft: true` together are refused.
## Amend before it goes out [#amend-before-it-goes-out]
```
advibly_social_update_post {
post_id,
caption: "...",
scheduled_at: "2026-10-02T09:00:00Z",
context: "Applying the user's requested caption and timing change to the scheduled campaign post before it publishes."
}
```
Edits are rejected within roughly five minutes of publish time. Past that
line, delete and recreate.
## Confirm and measure [#confirm-and-measure]
```
advibly_social_get_post {
post_id,
context: "Checking the per-platform publishing result of the scheduled campaign post to report status back to the user."
}
```
Publishing is per network, so one post can succeed on Instagram and fail on
TikTok. A failed post can be retried without recreating it.
For the week's results, `advibly_social_list_posts` returns posts with
performance, and `advibly_social_get_profile_stats` returns account-level
numbers.
A missing or disconnected profile in `advibly_social_list_accounts` means the
network authorisation lapsed. It has to be reconnected in [Settings →
Integrations](https://advibly.com/settings?tab=integrations); no MCP call can
renew it.
## Next [#next]
* Make the week's creative first:
[Launch campaign image set](/use-cases/launch-campaign-image-set).
* Feed it from long footage:
[Cut a long video into clips](/use-cases/clip-a-long-video).
---
# 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`.
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`.
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.
## 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).