- name
- arcads-video-marketing
- description
- Generate AI marketing videos and static image ads using Arcads external API with Seedance 2.0, Sora 2, Veo 3.1, Kling, Nano Banana, and 37-template Meta image library
- triggers
- ["create an arcads video","generate ugc video with seedance","make a nano banana image","create ai influencer character sheet","generate meta image ad","animate product with veo","build pixar style ad","make claymation video campaign"]
# Arcads AI Video Marketing Skill
> Skill by [ara.so](https://ara.so) — Claude Code Skills collection.
Create AI marketing videos and static image ads using the [Arcads](https://arcads.ai) external API. Supports the full creative stack: **Seedance 2.0** (flagship video model), **Sora 2**, **Veo 3.1**, **Kling 3.0**, **Grok Video**, **Nano Banana 2/Pro/Edit**, **ChatGPT Image 2**, **OmniHuman**, and **Audio-driven** video generation, plus a 37-template Meta image-ad library and multi-step pipelines for Pixar-style and claymation animated ads.
## Installation
### 1. Clone the repository
```bash
git clone https://github.com/krusemediallc/arcads-claude-code.git
cd arcads-claude-code
```
### 2. Run setup script
```bash
./scripts/setup.sh
```
This will:
- Prompt for your Arcads API key (get it at [app.arcads.ai/settings/api](https://app.arcads.ai/settings/api))
- Create `.env` file with your credentials
- Verify API connection
- Generate `MASTER_CONTEXT.md` workspace file
### 3. Install optional dependencies (for multi-step pipelines)
```bash
# macOS
brew install ffmpeg jq node
# Linux
apt install ffmpeg jq nodejs python3
# Python packages for specific workflows
pip install openai-whisper # For caption transcription
pip install -r shared/skills/meta-ad-builder/scripts/requirements.txt # For Meta API publishing
```
## Core API Structure
All API calls go through the Arcads base URL. The API key is stored in `.env`:
```bash
ARCADS_API_KEY=your_api_key_here
```
### Basic request pattern (Python)
```python
import os
import requests
import time
from dotenv import load_dotenv
load_dotenv()
api_key = os.getenv("ARCADS_API_KEY")
base_url = "https://api.arcads.ai"
headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
# Generate video
response = requests.post(
f"{base_url}/v1/seedance-2/video",
headers=headers,
json={
"prompt": "Woman in kitchen reviewing product, natural iPhone aesthetic",
"duration": 12,
"aspectRatio": "9:16"
}
)
job_id = response.json()["jobId"]
# Poll for completion
while True:
status_resp = requests.get(
f"{base_url}/v1/jobs/{job_id}",
headers=headers
)
status = status_resp.json()
if status["status"] == "completed":
video_url = status["result"]["videoUrl"]
print(f"Video ready: {video_url}")
break
elif status["status"] == "failed":
print(f"Failed: {status['error']}")
break
time.sleep(5)
```
## Video Generation Models
### Seedance 2.0 (Flagship Model)
**Endpoints:**
- `POST /v1/seedance-2/video` - Text or image-to-video (4-15s)
- `POST /v1/seedance-2/video-to-video` - Video-to-video transformation
**Key parameters:**
- `prompt` (string, required) - Scene description
- `duration` (int, 4-15) - Video length in seconds
- `aspectRatio` (string) - "16:9", "9:16", "1:1", "4:5"
- `startFrame` (string, optional) - Base64 image to start from
- `referenceImages` (array, optional) - Up to 3 base64 reference images
- `dialogue` (string, optional) - Embedded speech
- `shotStyle` (string, optional) - "static", "dynamic", "cinematic"
**Example: UGC selfie-style product review**
```python
def generate_seedance_ugc(product_name, duration=12):
"""Generate UGC video using 9-layer Seedance formula"""
prompt = f"""
iPhone selfie video, woman in bright kitchen holding {product_name}.
Natural eye-contact breaks, authentic delivery, vertical frame.
Warm lighting, casual outfit, product visible in hand.
Looking directly at camera, slight hand gestures, genuine smile.
Background: real kitchen counter, soft focus.
"""
payload = {
"prompt": prompt.strip(),
"duration": duration,
"aspectRatio": "9:16",
"shotStyle": "static",
"dialogue": f"I used to buy [competitor] but this {product_name} is so much better"
}
response = requests.post(
f"{base_url}/v1/seedance-2/video",
headers=headers,
json=payload
)
return response.json()["jobId"]
```
**Example: Premium product reveal (no person)**
```python
def generate_premium_reveal(product_name, features):
"""Dark void aesthetic with text narrative"""
prompt = f"""
{product_name} floating in dark void, dramatic spotlight from above.
Slow 360-degree rotation revealing product details.
Matte black background, professional studio lighting.
Text overlays appear: "{features}".
Cinematic depth, premium aesthetic, no person visible.
"""
payload = {
"prompt": prompt.strip(),
"duration": 10,
"aspectRatio": "1:1",
"shotStyle": "cinematic"
}
response = requests.post(
f"{base_url}/v1/seedance-2/video",
headers=headers,
json=payload
)
return response.json()["jobId"]
```
**Example: Image-to-video with reference**
```python
import base64
def seedance_with_reference(prompt_text, image_path, duration=8):
"""Start from a static image and animate it"""
with open(image_path, "rb") as f:
img_b64 = base64.b64encode(f.read()).decode()
payload = {
"prompt": prompt_text,
"duration": duration,
"aspectRatio": "9:16",
"startFrame": img_b64,
"shotStyle": "dynamic"
}
response = requests.post(
f"{base_url}/v1/seedance-2/video",
headers=headers,
json=payload
)
return response.json()["jobId"]
```
### Sora 2 (Long-form text-to-video)
**Endpoint:** `POST /v1/sora2/video`
**Parameters:**
- `prompt` (string, required)
- `duration` (int, 4-20) - Up to 20 seconds
- `aspectRatio` (string)
- `referenceImages` (array, optional) - Style references
```python
def generate_sora_video(scene_description, duration=16):
"""Sora 2 for longer-duration narrative videos"""
payload = {
"prompt": scene_description,
"duration": duration,
"aspectRatio": "16:9"
}
response = requests.post(
f"{base_url}/v1/sora2/video",
headers=headers,
json=payload
)
return response.json()["jobId"]
```
### Veo 3.1 (Start-frame animation)
**Endpoint:** `POST /v1/veo3/video`
**Best for:** Animating static UGC images into video with dialogue
```python
def animate_with_veo(image_path, dialogue_text, duration=8):
"""Animate a still image with embedded dialogue"""
with open(image_path, "rb") as f:
img_b64 = base64.b64encode(f.read()).decode()
payload = {
"startFrame": img_b64,
"dialogue": dialogue_text,
"duration": duration,
"aspectRatio": "9:16",
"prompt": "Natural human motion, authentic delivery, maintain starting pose"
}
response = requests.post(
f"{base_url}/v1/veo3/video",
headers=headers,
json=payload
)
return response.json()["jobId"]
```
### Kling 3.0 (B-roll and scenes)
**Endpoints:**
- `POST /v1/b-roll` - Quick environmental clips
- `POST /v1/scene` - Narrative scene generation
```python
def generate_broll(scene_type, duration=5):
"""Generate b-roll footage"""
broll_prompts = {
"coffee": "Steam rising from fresh coffee in ceramic mug, morning sunlight, warm tones",
"hands": "Hands typing on laptop keyboard, overhead shot, modern workspace",
"product": "Product on clean white surface, soft shadows, professional lighting"
}
payload = {
"prompt": broll_prompts.get(scene_type, scene_type),
"duration": duration,
"aspectRatio": "16:9"
}
response = requests.post(
f"{base_url}/v1/b-roll",
headers=headers,
json=payload
)
return response.json()["jobId"]
```
### Grok Video
**Endpoint:** `POST /v2/videos/generate`
```python
def generate_grok_video(prompt_text, duration=10):
"""Generate video using Grok Video model"""
payload = {
"model": "grok-video",
"prompt": prompt_text,
"duration": duration,
"aspectRatio": "16:9"
}
response = requests.post(
f"{base_url}/v2/videos/generate",
headers=headers,
json=payload
)
return response.json()["jobId"]
```
## Image Generation
### Nano Banana (Character-consistent images)
**Endpoints:**
- `POST /v1/nano-banana-2` - Default model
- `POST /v1/nano-banana` - Pro version (Gemini 3, tighter identity lock)
- `POST /v1/nano-banana-edit` - Inpainting
**Parameters:**
- `prompt` (string, required)
- `aspectRatio` (string)
- `referenceImages` (array, max 5) - For character consistency
- `refImageAsBase64` (string, optional) - Base reference
**Example: Create AI influencer character sheet**
```python
def create_ai_influencer(description, output_dir="references/influencers/"):
"""Generate 10-image character sheet for consistent AI influencer"""
# Phase 1: Generate hero portrait
hero_prompt = f"""
{description}
Front-facing portrait, direct eye contact, natural smile.
Professional but approachable lighting, sharp focus on face.
Neutral background, shoulders visible, genuine expression.
"""
response = requests.post(
f"{base_url}/v1/nano-banana-2",
headers=headers,
json={
"prompt": hero_prompt.strip(),
"aspectRatio": "4:5"
}
)
hero_job_id = response.json()["jobId"]
# Wait for hero to complete
hero_img = poll_and_download(hero_job_id)
print("Hero portrait ready. Generating 9 additional angles...")
# Phase 2: Generate 9 additional angles using hero as reference
with open(hero_img, "rb") as f:
hero_b64 = base64.b64encode(f.read()).decode()
angles = [
"3/4 profile view, slight turn to left",
"3/4 profile view, slight turn to right",
"Full profile view, side of face",
"Close-up of face, tighter crop",
"Laughing expression, natural joy",
"Serious expression, focused",
"Upper body, arms visible, casual pose",
"Holding phone, looking at camera",
"In different lighting, golden hour"
]
job_ids = []
for angle in angles:
payload = {
"prompt": f"{description}. {angle}",
"aspectRatio": "4:5",
"referenceImages": [hero_b64]
}
resp = requests.post(
f"{base_url}/v1/nano-banana-2",
headers=headers,
json=payload
)
job_ids.append(resp.json()["jobId"])
return hero_job_id, job_ids
```
**Example: UGC product selfie still**
```python
def generate_ugc_selfie(character_ref_path, product_ref_path, setting="bedroom"):
"""Generate authentic UGC selfie with product"""
# Load reference images
with open(character_ref_path, "rb") as f:
char_b64 = base64.b64encode(f.read()).decode()
with open(product_ref_path, "rb") as f:
View on GitHub