Skip to content

Repository files navigation

vibes-api

Unofficial Python API client for vibes.ai β€” Meta's AI video creation studio. Generate videos, images, TTS, lip-sync, and more, all from a Python script or CLI.

This package was built by reverse-engineering the vibes.ai Next.js bundles and observing real network traffic. It is not affiliated with, endorsed by, or officially supported by Meta or Vibes.


⚑ Quick start

# 1) Install
pip install VibesAI-api

# 2) Set your cookie (grab from DevTools β†’ Application β†’ Cookies β†’ vibes.ai)
export VIBES_META_SESSION="e60e910a-242a-...-K54E"

# 3) Generate your first video
vibes-api one-shot \
  --prompt "A serene mountain landscape at sunset" \
  --aspect-ratio 16:9 --resolution 720p --variations 4 \
  --download-dir ./out

Or in Python:

from vibes_api import VibesClient, AspectRatio, Resolution

client = VibesClient(meta_session="...")
project = client.create_project(name="My Video")
batch = client.generate_video(
    project_id=project["id"],
    prompt="A serene mountain landscape at sunset",
    aspect_ratio=AspectRatio.LANDSCAPE,
    resolution=Resolution.P720,
    variations=4,
)
client.download_video(batch["content"][0]["id"], "sunset.mp4")

πŸ“¦ What's inside

Core capabilities (v1.1.0)

Feature Method Notes
Auth get_me(), get_system_status(), logout() Cookie-based
Projects list_projects(), create_project(), get_project(), update_project(), delete_project(), duplicate_project()
Video generation (t2v) generate_video() text-to-video, 1-4 variations
Image generation (t2i) generate_image() synchronous, returns immediately
πŸŽ₯ Video extend (auto) auto_extend_video(), extend_video(prompt=None) extends a video by ~5s, no directive
πŸŽ₯ Video extend (manual) manual_extend_video(), extend_video(prompt=...) extends with a directive prompt
πŸŽ₯ Video edit (v2v) edit_video() re-render existing video with a directive
πŸŽ₯ Image animate (auto) auto_animate_image() animate a still image with original prompt
πŸŽ₯ Image animate (manual) manual_animate_image() animate with a directive prompt
πŸ”„ Regenerate batch regenerate_batch() re-roll with same or new prompt
πŸ–ΌοΈ Image editing edit_image() prompt-driven edits
✨ Prompt enhancement enhance_prompt() returns 4 AI-rewritten variations
πŸ—£οΈ Lip sync generate_lipsync() image + audio + script β†’ video
πŸ”Š TTS tts(), list_voices(), save_tts_audio() 41 preset voices
🎭 Start/end frame generate_video(start_frame=..., end_frame=...), build_frame_handle() image-to-video with keyframes
πŸ§™ Ingredients (character/style/scene) list_characters(), list_styles(), list_scenes(), create_ingredient(), delete_ingredient() studio ingredient CRUD
πŸ§™ Ingredient refs in generation ingredients=[...], create_ingredients=[...] apply or inline-create
🎨 Moodboards list_moodboards(), get_moodboard(), create_moodboard(), delete_moodboard()
⬆️ Uploads upload_image(), upload_image_file(), upload_video_direct(), upload_audio_direct(), upload_media(), upload_profile_picture()
πŸ“š Media library list_media(), favorite_content_item(), delete_content_item(), delete_content_items()
⬇️ Download download_video(), download_image()
πŸ”— Share links create_share_link(), list_share_links(), revoke_share_link()
🎡 Music library search_music(), lookup_music_thumbnail(), clip_music(), clip_audio()
πŸ’¬ Timeline chat timeline_chat() streaming AI assistant (SSE)
🎬 Timeline export export_timeline(), export_timeline_async(), check_export_status(), cancel_export() render composition β†’ MP4
πŸ”„ Real-time sync get_sync_status(), stream_sync_updates(), stream_batch_updates() SSE for collaborative editing
πŸ“Š Quota get_quota_upsell()
βš™οΈ Account settings delete_account(), delete_all_media(), remove_all_posts()
πŸ› Bug reports report_bug(), record_consent()
🀝 Collaborators list_collaborators(), remove_collaborator()
πŸ“¦ Project assets list_project_assets(), add_project_asset(), import_project_assets(), list_available_assets() cross-project reuse
⏳ Batch polling poll_batch(), list_batches(), list_project_batches(), get_batch(), delete_batch()
πŸš€ One-shot create_video_from_prompt() end-to-end convenience

CLI

The vibes-api CLI exposes every feature as a subcommand. Run vibes-api --help for the full list.

# User
vibes-api me

# Projects
vibes-api projects list
vibes-api projects create --name "My Video"
vibes-api projects get <id>
vibes-api projects delete <id> --delete-assets

# Video generation
vibes-api videos generate --project-id <id> --prompt "sunset over ocean" \
  --aspect-ratio 16:9 --resolution 720p --variations 4 --download-dir ./out

# πŸ†• Video extend (auto/manual)
vibes-api videos extend --project-id <id> --batch-id <batch> \
  --content-id <content>  # auto-extend (no --prompt)
vibes-api videos extend --project-id <id> --batch-id <batch> \
  --prompt "camera pans up to reveal the sky"  # manual extend

# πŸ†• Video edit (v2v)
vibes-api videos edit --project-id <id> --batch-id <batch> \
  --prompt "change the weather to rain"

# Image generation
vibes-api images generate --project-id <id> --prompt "cyberpunk city"

# πŸ†• Image animate (auto/manual)
vibes-api images animate --project-id <id> --content-id <content>
vibes-api images animate --project-id <id> --content-id <content> \
  --prompt "camera zooms in slowly"

# πŸ†• Batch regenerate (re-roll)
vibes-api batches regenerate <batch-id> --project-id <id>
vibes-api batches regenerate <batch-id> --project-id <id> --prompt "new prompt"

# πŸ†• Ingredient CRUD
vibes-api ingredients list [--type CHARACTER|STYLE|SETTING]
vibes-api ingredients create --name "My Character" --type CHARACTER \
  --image-ent-id <id> --image-url <url>
vibes-api ingredients delete <ingredient_id>

# TTS
vibes-api voices list
vibes-api tts --voice play_ai_Marisol --text "Hello world" --out hello.mp3

# Media library
vibes-api media list --type video --limit 10
vibes-api media download --id <id> --out video.mp4
vibes-api media delete --ids <id1> <id2>

# Prompt enhancement
vibes-api prompts enhance --prompt "a cat"

# Share links
vibes-api share create --entity-type project --entity-id <id>
vibes-api share list --entity-type project --entity-id <id>
vibes-api share revoke <share_link_id>

# Batches
vibes-api batches list --project-id <id>
vibes-api batches get <batch_id>
vibes-api batches poll <batch_id> --timeout 180

# Music
vibes-api music search --query "lofi"

# Timeline AI chat
vibes-api chat "add a 5 second sunset clip"

# πŸ†• Real-time sync
vibes-api sync status --entity-type project --entity-id <id>
vibes-api sync stream --entity-type project --entity-id <id>  # Ctrl+C to stop

# πŸ†• Quota
vibes-api quota

# End-to-end one-shot
vibes-api one-shot --prompt "sunset over ocean" --download-dir ./out

🎬 Generation flow (under the hood)

Vibes uses a two-step generation pattern:

1) POST /api/generation-batches    β†’ create a batch shell (with client-generated UUID v7)
2) POST /api/generate/videos       β†’ trigger actual generation
3) GET  /api/generation-batches/{id} β†’ poll until isComplete=true
                                     OR  /api/generation-batches/{id}/stream (SSE)

The client abstracts this away behind generate_video() (which polls by default) and generate_image() (which is synchronous).

Batch IDs are UUID v7 with batch- prefix

The server expects batch IDs to be UUID v7 (timestamp-ordered) prefixed with batch- so it can derive the creation time from the high bits AND so that the download endpoint accepts the content IDs. The client generates these internally via _uuid_v7(). Special flows use different prefixes:

  • batch-<uuid_v7> β€” normal text/image generation
  • extend-<timestamp>-<random> β€” video extension
  • image2video-<timestamp>-<random> β€” image-to-video (animate)
  • video2video-<timestamp>-<random> β€” video-to-video (edit)

Aspect ratios & resolutions

Only 3 aspect ratios are supported (verified live):

Aspect Image dimensions Notes
1:1 1280Γ—1280 Square
9:16 720Γ—1280 Portrait (UI default)
16:9 1280Γ—720 Landscape

Resolutions: 480p (default, faster) and 720p (slower but higher quality).

Models

Type Default model Description
Image midjen-base Standard image generation
Video (t2v / i2v) midjen-short ~5 second clips
Video extend midjen-extend For extending an existing video
Video edit (v2v) midjen-video-edit For re-rendering with a directive
Lip sync lipsync / midjen-lipsync-async Lip-sync generation
Prompt LLM gemini-2.5-flash Used for prompt enhancement

Generation types

generationType When to use
t2v text β†’ video
t2i text β†’ image
i2v image (start frame) β†’ video
extend extend an existing video
v2v video β†’ video (re-render with directive)
lipsync lip-sync generation

🎭 Ingredients (characters, styles, scenes)

Vibes supports three ingredient types:

  • CHARACTER (UI: "Character") β€” applies via orefImageHandle internally
  • STYLE (UI: "Style") β€” applies via srefImageHandle internally
  • SETTING (UI: "Scene") β€” applies via settingImageHandles internally

There are three ways to reference an ingredient in a generation:

from vibes_api import IngredientType
from vibes_api.ingredients import IngredientRef, CreateIngredient

# 1. By existing ingredient ID (from list_ingredients)
character = IngredientRef.by_id(
    ingredient_id="800957099700717",
    ingredient_type=IngredientType.CHARACTER,
    name="Valdrin",
    image_url="https://...",
)

# 2. By uploaded image entity ID (creates a new ingredient on-the-fly)
style = CreateIngredient.by_image_ent_id(
    image_ent_id="1177...",
    ingredient_type=IngredientType.STYLE,
    name="Cyberpunk neon",
    image_url="https://...",
)

# 3. By name only (uses prompt-generated image)
scene = CreateIngredient.by_name(
    ingredient_type=IngredientType.SETTING,
    name="Misty forest at dawn",
)

# Pass them to generate_video
batch = client.generate_video(
    project_id=project["id"],
    prompt="...",
    ingredients=[character],            # goes in `ingredients[]`
    create_ingredients=[style, scene],  # goes in `createIngredients[]`
)

You can also CRUD ingredients directly:

  • client.list_characters(), list_styles(), list_scenes()
  • client.create_ingredient(name, ingredient_type, source_image_ent_id, ...)
  • client.delete_ingredient(ingredient_id)

πŸ–ΌοΈ Start/end frame (image-to-video with keyframes)

Generate a video that interpolates between two keyframes:

# Generate the start frame image
start_resp = client.generate_image(
    project_id=project["id"],
    prompt="a rose in full bloom",
    aspect_ratio="16:9",
)
# Generate the end frame image
end_resp = client.generate_image(
    project_id=project["id"],
    prompt="a withered, dried rose",
    aspect_ratio="16:9",
)

# Build frame handles
start_frame = client.build_frame_handle({
    "mediaEntId": start_resp["data"][0]["imageEntId"],
    "imageUrl": start_resp["data"][0]["url"],
})
end_frame = client.build_frame_handle({
    "mediaEntId": end_resp["data"][0]["imageEntId"],
    "imageUrl": end_resp["data"][0]["url"],
})

# Generate the video with both keyframes
batch = client.generate_video(
    project_id=project["id"],
    prompt="the rose slowly wilts, time-lapse effect",
    start_frame=start_frame,
    end_frame=end_frame,
    aspect_ratio="16:9",
)

For a single start frame (i2v without end frame), just omit end_frame.


πŸŽ₯ Video extend (auto + manual)

The Vibes UI shows "Auto extend" and "Manual extend" buttons next to each generated video. Both call the same backend β€” the only difference is whether you supply a directive prompt:

# Get a previously-generated video's full content item
batch = client.get_batch("batch-...")
source_video = batch["content"][0]

# AUTO extend: no prompt, server continues original
extended_auto = client.extend_video(
    project_id=project["id"],
    source_video=source_video,
)

# MANUAL extend: provide a directive
extended_manual = client.manual_extend_video(
    project_id=project["id"],
    source_video=source_video,
    prompt="camera pans up to reveal the sky",
)

The source_video dict must be the full content item (not just an ID) because extend needs the original videoHandle, videoGenEntId, and structuredOutput from the source.


πŸ”‘ Authentication

Vibes uses a single cookie, meta_session, for authentication. The cookie value is a UUID session token.

How to get your cookie

  1. Log in at vibes.ai in your browser (currently requires a Meta/Facebook account).

  2. Open DevTools (F12) β†’ Application β†’ Cookies β†’ https://vibes.ai.

  3. Copy the value of meta_session (a long string with a UUID format like e60e910a-...-K54E).

  4. Pass it to the client:

    client = VibesClient(meta_session="e60e910a-...")

    Or via env var:

    export VIBES_META_SESSION="e60e910a-..."

Cookie rotation

Cookies expire. The web app refreshes them silently via /api/auth/me. When you start getting 401 Unauthorized errors, grab a fresh cookie from the browser and create a new VibesClient. You said you'll rotate them β€” this is the only manual step.

TTS-specific limitation

The TTS endpoint (/api/studio/playai/tts) depends on a server-side Facebook access token that rotates independently of your meta_session. If you see 403 Facebook expired access token, just wait a few minutes and retry. The Vibes backend auto-refreshes this token on its own schedule.


πŸ“‘ API endpoint reference

All endpoints are under https://vibes.ai/api/. This list was extracted directly from the Next.js JS bundles.

Auth & system

  • GET /api/auth/me β€” current user
  • POST /api/auth/logout β€” invalidate session
  • POST /api/auth/check-token β€” token validation
  • GET /api/system-status β€” system status banner
  • POST /api/analytics β€” usage analytics (fire-and-forget)
  • POST /api/bug-report β€” bug reporting
  • POST /api/consent/record β€” cookie consent
  • GET /api/quota/upsell β€” upsell info

Projects

  • GET /api/projects β€” list (params: limit, offset, sort, search)
  • POST /api/projects β€” create
  • GET /api/projects/{id} β€” get
  • PUT /api/projects/{id} β€” update name/composition
  • DELETE /api/projects/{id}?deleteAssets=true β€” delete
  • POST /api/projects/{id}/duplicate β€” duplicate
  • POST /api/projects/{id}/upload β€” bulk upload media
  • GET /api/projects/{id}/batches?limit=6&offset=0 β€” list batches in project
  • GET /api/projects/{id}/assets β€” list project assets
  • POST /api/projects/{id}/assets β€” add asset
  • POST /api/projects/{id}/assets/import β€” import from another project
  • GET /api/projects/{id}/assets/available?sourceProjectId={id} β€” list importable
  • POST /api/projects/{id}/timeline/download β€” sync export to MP4
  • POST /api/projects/{id}/timeline/export-surfguard β€” start async export
  • GET /api/projects/{id}/timeline/export/{exportId}/status β€” poll export
  • POST /api/projects/{id}/timeline/export/{exportId}/cancel β€” cancel

Generation batches

  • GET /api/generation-batches?limit=12&offset=0 β€” list (optional projectId, type)
  • POST /api/generation-batches β€” create (body must include client-generated UUID v7 as id)
  • GET /api/generation-batches/{id} β€” get full state
  • PUT /api/generation-batches/{id} β€” update
  • DELETE /api/generation-batches/{id} β€” delete
  • GET /api/generation-batches/{id}/stream β€” SSE stream of batch updates

Generation

  • POST /api/generate/videos β€” text-to-video, image-to-video, extend, v2v edit, image animate (all via different type and config values)
  • POST /api/generate/images β€” text-to-image (synchronous)
  • POST /api/generate/image-edit β€” edit an existing image
  • POST /api/generate/prompts β€” prompt enhancement (returns 4 variations)
  • POST /api/animate/generate β€” lip sync / animation

Studio

  • GET /api/studio/ingredients?ownerFilter=LIBRARY|VIEWER&ingredientType=... β€” list ingredients
  • POST /api/studio/ingredients β€” create ingredient
  • DELETE /api/studio/ingredients/{id} β€” delete ingredient
  • GET /api/studio/voices β€” list TTS voices
  • POST /api/studio/playai/tts β€” text-to-speech (body: {text, voice, outputFormat, language?})

Uploads

  • POST /api/upload-image β€” base64 image upload (body: {image: "<base64>"})
  • POST /api/upload-media β€” multipart form (file + filename)
  • POST /api/upload-video-direct β€” multipart form (video)
  • POST /api/upload-audio-direct β€” multipart form (audio)
  • POST /api/upload-profile-picture β€” profile picture

Media library & content items

  • GET /api/media-library?limit=50&offset=0&type=&sort=&search= β€” list
  • GET /api/download/video?id={contentItemId} β€” download video MP4
  • GET /api/download/png?id={contentItemId} β€” download image PNG
  • GET /api/download/{type}?id={id} β€” generic download
  • POST /api/content-items/{id}/favorite β€” toggle favorite
  • POST /api/content-items/{id}/retry β€” retry failed item
  • POST /api/content-items/{id}/feedback β€” submit feedback
  • DELETE /api/content-items/{id} β€” delete one
  • POST /api/content-items/bulk-delete β€” bulk delete (body: {ids: [...]})

Audio / music

  • GET /api/meta-music?q=&limit=&cursor= β€” search Meta music library
  • GET /api/meta-music/lookup?id=&title= β€” resolve track thumbnail
  • POST /api/meta-music/oa-check β€” check original audio status
  • POST /api/media/music/clip β€” clip a music track segment
  • POST /api/media/audio/clip β€” clip any audio URL
  • GET /api/proxy-audio β€” proxy audio through Vibes CDN
  • GET /api/resolve-audio-urls β€” resolve audio CDN URLs

Moodboards & playables

  • GET /api/moodboards β€” list
  • POST /api/moodboards β€” create
  • GET /api/moodboards/{id} β€” get
  • DELETE /api/moodboards/{id} β€” delete
  • GET /api/playables β€” list playables (currently disabled: "Playables not enabled")

Timeline AI

  • POST /api/timeline/chat/stream β€” streaming SSE chat (body: {input, instructions, tools?, composition?})
    • Event types: message_delta, message_done, tool_call, tool_response, reasoning_delta, reasoning_done, completed, error
    • Default tools (sent by the client): generate_image, generate_video, add_music, add_text_overlay, update_text_overlay, resize_clip, move_clip, extend_timeline_to, delete_clip, delete_track, split_clip, duplicate_clip, set_fade, set_volume, set_speed, mute_track, rename_track, reorder_clips, generate_lipsync, create_ingredient_from_clip

Share & collaborators

  • POST /api/share-links β€” create (body: {entityType, entityId, expiresAt?, maxUses?})
  • GET /api/share-links?entityType=&entityId= β€” list
  • DELETE /api/share-links/{id} β€” revoke
  • GET /api/collaborators?entityType=&entityId= β€” list
  • DELETE /api/collaborators/{id} β€” remove

πŸ†• Real-time sync (SSE)

  • GET /api/sync?entityType=&entityId= β€” get last-updated timestamp
  • GET /api/sync/stream?entityType=&entityId= β€” SSE stream of update events (snapshot, update, bye)

Settings

  • POST /api/settings/delete-account
  • POST /api/settings/delete-all-media
  • POST /api/settings/remove-all-posts

Meta integration

  • POST /api/meta-graphql β€” Meta GraphQL proxy (body: {doc_id, variables})
  • POST /api/meta-oidc/start β€” start OIDC flow
  • POST /api/meta-profiles/publish β€” publish profile
  • POST /api/revisions β€” session revisions

πŸ§ͺ Examples

Ten ready-to-run example scripts in examples/:

  1. 01_generate_video.py β€” end-to-end video generation
  2. 02_images_and_edits.py β€” image generation + editing + media library
  3. 03_tts_and_lipsync.py β€” TTS β†’ upload β†’ lip sync pipeline
  4. 04_prompts_and_chat.py β€” prompt enhancement + timeline AI chat
  5. 05_ingredients.py β€” using saved characters in generations
  6. 06_extend_video.py β€” πŸ†• auto-extend and manual-extend a video
  7. 07_ingredients_full.py β€” πŸ†• character + style + scene combos
  8. 08_create_ingredient.py β€” πŸ†• create a new ingredient via API
  9. 09_start_end_frame.py β€” πŸ†• image-to-video with keyframe interpolation
  10. 10_edit_video.py β€” πŸ†• video-to-video editing (re-render with directive)

Run any of them with:

export VIBES_META_SESSION="..."
python /home/z/my-project/download/vibes-api/examples/01_generate_video.py

⚠️ Limitations & caveats

  1. Cookie rotation β€” meta_session expires. Re-grab from the browser when 401s appear.
  2. TTS backend token β€” /api/studio/playai/tts depends on a server-side FB token that rotates independently. If you get 403 Facebook expired access token, wait and retry.
  3. Generation quotas β€” Vibes enforces per-user quotas (visible in the UI). Hit it and you'll get 429 or a GENERATION_FAILED with quota detail.
  4. No public API β€” All endpoints here are private and could change at any time. Pin to a client version if stability matters.
  5. Content IDs for download β€” download_video(id) expects the format batch-{uuid}-content-{n}. The client uses the batch- prefix consistently so this works for client-generated batches.
  6. Rate limiting β€” Don't hammer the API. The client uses a single requests.Session; if you need parallelism, instantiate multiple clients and rotate cookies.
  7. Aspect ratios β€” Only 1:1, 9:16, 16:9 are supported (server-enforced). Other values return GENERATION_FAILED.
  8. Video extend requires full content item β€” extend_video(source_video=...) needs the full content item dict (from get_batch()), not just an ID. The client extracts videoHandle, videoGenEntId, and structuredOutput from it.
  9. v2v edit may fail on old videos β€” edit_video() requires videoHandle metadata which older videos may not have. You'll get a clear error message in that case.
  10. Sentry analytics β€” The web app posts to Sentry for error tracking. This client does not replicate that (it's noise for API use).

πŸ› οΈ Development

# Install in editable mode
pip install VibesAI-api

# Run tests (requires VIBES_META_SESSION env var)
pytest

# Build CLI
python -m vibes_api.cli --help

Project layout

vibes-api/
β”œβ”€β”€ pyproject.toml
β”œβ”€β”€ README.md
β”œβ”€β”€ QUICKREF.md
β”œβ”€β”€ TEST_RESULTS.md
β”œβ”€β”€ vibes_api/
β”‚   β”œβ”€β”€ __init__.py       # Public API surface
β”‚   β”œβ”€β”€ client.py         # VibesClient main implementation (~2400 lines, 87 methods)
β”‚   β”œβ”€β”€ cli.py            # Argparse-based CLI
β”‚   β”œβ”€β”€ models.py         # Enums: AspectRatio, Resolution, VideoModel, etc.
β”‚   └── ingredients.py    # Ingredient payload builders
β”œβ”€β”€ examples/
β”‚   β”œβ”€β”€ 01_generate_video.py
β”‚   β”œβ”€β”€ 02_images_and_edits.py
β”‚   β”œβ”€β”€ 03_tts_and_lipsync.py
β”‚   β”œβ”€β”€ 04_prompts_and_chat.py
β”‚   β”œβ”€β”€ 05_ingredients.py
β”‚   β”œβ”€β”€ 06_extend_video.py        # πŸ†•
β”‚   β”œβ”€β”€ 07_ingredients_full.py    # πŸ†•
β”‚   β”œβ”€β”€ 08_create_ingredient.py   # πŸ†•
β”‚   β”œβ”€β”€ 09_start_end_frame.py     # πŸ†•
β”‚   └── 10_edit_video.py          # πŸ†•
└── research/
    └── ... (reversing notes, sample responses, screenshots)

πŸ“œ License

MIT. This project is not affiliated with Meta or Vibes. Use at your own risk; respect Vibes' Terms of Service.

About

Unofficial Python API client for vibes.ai - generate videos, images, TTS, lip-sync, manage timelines, publish, and more (127 methods, 106 tests)

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages