VibesAI-api 1.3.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vibesai_api-1.3.2/LICENSE +28 -0
- vibesai_api-1.3.2/PKG-INFO +600 -0
- vibesai_api-1.3.2/README.md +581 -0
- vibesai_api-1.3.2/VibesAI_api.egg-info/PKG-INFO +600 -0
- vibesai_api-1.3.2/VibesAI_api.egg-info/SOURCES.txt +18 -0
- vibesai_api-1.3.2/VibesAI_api.egg-info/dependency_links.txt +1 -0
- vibesai_api-1.3.2/VibesAI_api.egg-info/entry_points.txt +2 -0
- vibesai_api-1.3.2/VibesAI_api.egg-info/requires.txt +10 -0
- vibesai_api-1.3.2/VibesAI_api.egg-info/top_level.txt +2 -0
- vibesai_api-1.3.2/pyproject.toml +23 -0
- vibesai_api-1.3.2/server/__init__.py +3 -0
- vibesai_api-1.3.2/server/app.py +332 -0
- vibesai_api-1.3.2/setup.cfg +4 -0
- vibesai_api-1.3.2/tests/test_all.py +717 -0
- vibesai_api-1.3.2/vibes_api/__init__.py +121 -0
- vibesai_api-1.3.2/vibes_api/cli.py +852 -0
- vibesai_api-1.3.2/vibes_api/client.py +3972 -0
- vibesai_api-1.3.2/vibes_api/composition.py +852 -0
- vibesai_api-1.3.2/vibes_api/ingredients.py +206 -0
- vibesai_api-1.3.2/vibes_api/models.py +165 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 vibes-api contributors
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
---
|
|
24
|
+
|
|
25
|
+
This project is NOT affiliated with, endorsed by, or officially supported by
|
|
26
|
+
Meta Platforms, Inc. or Vibes. "Vibes" and "Meta" are trademarks of their
|
|
27
|
+
respective owners. Use of this software is at your own risk; respect the
|
|
28
|
+
Vibes Terms of Service at https://vibes.ai/.
|
|
@@ -0,0 +1,600 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: VibesAI-api
|
|
3
|
+
Version: 1.3.2
|
|
4
|
+
Summary: Unofficial Python API client for vibes.ai
|
|
5
|
+
Author-email: Ashiq Hussain Mir <imsrenpsycho@gmail.com>
|
|
6
|
+
License: MIT
|
|
7
|
+
Requires-Python: >=3.8
|
|
8
|
+
Description-Content-Type: text/markdown
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Requires-Dist: requests>=2.28.0
|
|
11
|
+
Provides-Extra: server
|
|
12
|
+
Requires-Dist: fastapi>=0.104.0; extra == "server"
|
|
13
|
+
Requires-Dist: uvicorn[standard]>=0.24.0; extra == "server"
|
|
14
|
+
Requires-Dist: pydantic>=2.0.0; extra == "server"
|
|
15
|
+
Requires-Dist: Pillow>=10.0.0; extra == "server"
|
|
16
|
+
Provides-Extra: dev
|
|
17
|
+
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
18
|
+
Dynamic: license-file
|
|
19
|
+
|
|
20
|
+
# vibes-api
|
|
21
|
+
|
|
22
|
+
> **Unofficial** Python API client for [vibes.ai](https://vibes.ai/) — Meta's AI video creation studio. Generate videos, images, TTS, lip-sync, and more, all from a Python script or CLI.
|
|
23
|
+
|
|
24
|
+
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.
|
|
25
|
+
|
|
26
|
+
---
|
|
27
|
+
|
|
28
|
+
## ⚡ Quick start
|
|
29
|
+
|
|
30
|
+
```bash
|
|
31
|
+
# 1) Install
|
|
32
|
+
pip install -e /home/z/my-project/download/vibes-api
|
|
33
|
+
|
|
34
|
+
# 2) Set your cookie (grab from DevTools → Application → Cookies → vibes.ai)
|
|
35
|
+
export VIBES_META_SESSION="e60e910a-242a-...-K54E"
|
|
36
|
+
|
|
37
|
+
# 3) Generate your first video
|
|
38
|
+
vibes-api one-shot \
|
|
39
|
+
--prompt "A serene mountain landscape at sunset" \
|
|
40
|
+
--aspect-ratio 16:9 --resolution 720p --variations 4 \
|
|
41
|
+
--download-dir ./out
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
Or in Python:
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from vibes_api import VibesClient, AspectRatio, Resolution
|
|
48
|
+
|
|
49
|
+
client = VibesClient(meta_session="...")
|
|
50
|
+
project = client.create_project(name="My Video")
|
|
51
|
+
batch = client.generate_video(
|
|
52
|
+
project_id=project["id"],
|
|
53
|
+
prompt="A serene mountain landscape at sunset",
|
|
54
|
+
aspect_ratio=AspectRatio.LANDSCAPE,
|
|
55
|
+
resolution=Resolution.P720,
|
|
56
|
+
variations=4,
|
|
57
|
+
)
|
|
58
|
+
client.download_video(batch["content"][0]["id"], "sunset.mp4")
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
---
|
|
62
|
+
|
|
63
|
+
## 📦 What's inside
|
|
64
|
+
|
|
65
|
+
### Core capabilities (v1.1.0)
|
|
66
|
+
|
|
67
|
+
| Feature | Method | Notes |
|
|
68
|
+
|---|---|---|
|
|
69
|
+
| **Auth** | `get_me()`, `get_system_status()`, `logout()` | Cookie-based |
|
|
70
|
+
| **Projects** | `list_projects()`, `create_project()`, `get_project()`, `update_project()`, `delete_project()`, `duplicate_project()` | |
|
|
71
|
+
| **Video generation (t2v)** | `generate_video()` | text-to-video, 1-4 variations |
|
|
72
|
+
| **Image generation (t2i)** | `generate_image()` | synchronous, returns immediately |
|
|
73
|
+
| **🎥 Video extend (auto)** | `auto_extend_video()`, `extend_video(prompt=None)` | extends a video by ~5s, no directive |
|
|
74
|
+
| **🎥 Video extend (manual)** | `manual_extend_video()`, `extend_video(prompt=...)` | extends with a directive prompt |
|
|
75
|
+
| **🎥 Video edit (v2v)** | `edit_video()` | re-render existing video with a directive |
|
|
76
|
+
| **🎥 Image animate (auto)** | `auto_animate_image()` | animate a still image with original prompt |
|
|
77
|
+
| **🎥 Image animate (manual)** | `manual_animate_image()` | animate with a directive prompt |
|
|
78
|
+
| **🔄 Regenerate batch** | `regenerate_batch()` | re-roll with same or new prompt |
|
|
79
|
+
| **🖼️ Image editing** | `edit_image()` | prompt-driven edits |
|
|
80
|
+
| **✨ Prompt enhancement** | `enhance_prompt()` | returns 4 AI-rewritten variations |
|
|
81
|
+
| **🗣️ Lip sync** | `generate_lipsync()` | image + audio + script → video |
|
|
82
|
+
| **🔊 TTS** | `tts()`, `list_voices()`, `save_tts_audio()` | 41 preset voices |
|
|
83
|
+
| **🎭 Start/end frame** | `generate_video(start_frame=..., end_frame=...)`, `build_frame_handle()` | image-to-video with keyframes |
|
|
84
|
+
| **🧙 Ingredients (character/style/scene)** | `list_characters()`, `list_styles()`, `list_scenes()`, `create_ingredient()`, `delete_ingredient()` | studio ingredient CRUD |
|
|
85
|
+
| **🧙 Ingredient refs in generation** | `ingredients=[...]`, `create_ingredients=[...]` | apply or inline-create |
|
|
86
|
+
| **🎨 Moodboards** | `list_moodboards()`, `get_moodboard()`, `create_moodboard()`, `delete_moodboard()` | |
|
|
87
|
+
| **⬆️ Uploads** | `upload_image()`, `upload_image_file()`, `upload_video_direct()`, `upload_audio_direct()`, `upload_media()`, `upload_profile_picture()` | |
|
|
88
|
+
| **📚 Media library** | `list_media()`, `favorite_content_item()`, `delete_content_item()`, `delete_content_items()` | |
|
|
89
|
+
| **⬇️ Download** | `download_video()`, `download_image()` | |
|
|
90
|
+
| **🔗 Share links** | `create_share_link()`, `list_share_links()`, `revoke_share_link()` | |
|
|
91
|
+
| **🎵 Music library** | `search_music()`, `lookup_music_thumbnail()`, `clip_music()`, `clip_audio()` | |
|
|
92
|
+
| **💬 Timeline chat** | `timeline_chat()` | streaming AI assistant (SSE) |
|
|
93
|
+
| **🎬 Timeline export** | `export_timeline()`, `export_timeline_async()`, `check_export_status()`, `cancel_export()` | render composition → MP4 |
|
|
94
|
+
| **🔄 Real-time sync** | `get_sync_status()`, `stream_sync_updates()`, `stream_batch_updates()` | SSE for collaborative editing |
|
|
95
|
+
| **📊 Quota** | `get_quota_upsell()` | |
|
|
96
|
+
| **⚙️ Account settings** | `delete_account()`, `delete_all_media()`, `remove_all_posts()` | |
|
|
97
|
+
| **🐛 Bug reports** | `report_bug()`, `record_consent()` | |
|
|
98
|
+
| **🤝 Collaborators** | `list_collaborators()`, `remove_collaborator()` | |
|
|
99
|
+
| **📦 Project assets** | `list_project_assets()`, `add_project_asset()`, `import_project_assets()`, `list_available_assets()` | cross-project reuse |
|
|
100
|
+
| **⏳ Batch polling** | `poll_batch()`, `list_batches()`, `list_project_batches()`, `get_batch()`, `delete_batch()` | |
|
|
101
|
+
| **🚀 One-shot** | `create_video_from_prompt()` | end-to-end convenience |
|
|
102
|
+
|
|
103
|
+
### CLI
|
|
104
|
+
|
|
105
|
+
The `vibes-api` CLI exposes every feature as a subcommand. Run `vibes-api --help` for the full list.
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# User
|
|
109
|
+
vibes-api me
|
|
110
|
+
|
|
111
|
+
# Projects
|
|
112
|
+
vibes-api projects list
|
|
113
|
+
vibes-api projects create --name "My Video"
|
|
114
|
+
vibes-api projects get <id>
|
|
115
|
+
vibes-api projects delete <id> --delete-assets
|
|
116
|
+
|
|
117
|
+
# Video generation
|
|
118
|
+
vibes-api videos generate --project-id <id> --prompt "sunset over ocean" \
|
|
119
|
+
--aspect-ratio 16:9 --resolution 720p --variations 4 --download-dir ./out
|
|
120
|
+
|
|
121
|
+
# 🆕 Video extend (auto/manual)
|
|
122
|
+
vibes-api videos extend --project-id <id> --batch-id <batch> \
|
|
123
|
+
--content-id <content> # auto-extend (no --prompt)
|
|
124
|
+
vibes-api videos extend --project-id <id> --batch-id <batch> \
|
|
125
|
+
--prompt "camera pans up to reveal the sky" # manual extend
|
|
126
|
+
|
|
127
|
+
# 🆕 Video edit (v2v)
|
|
128
|
+
vibes-api videos edit --project-id <id> --batch-id <batch> \
|
|
129
|
+
--prompt "change the weather to rain"
|
|
130
|
+
|
|
131
|
+
# Image generation
|
|
132
|
+
vibes-api images generate --project-id <id> --prompt "cyberpunk city"
|
|
133
|
+
|
|
134
|
+
# 🆕 Image animate (auto/manual)
|
|
135
|
+
vibes-api images animate --project-id <id> --content-id <content>
|
|
136
|
+
vibes-api images animate --project-id <id> --content-id <content> \
|
|
137
|
+
--prompt "camera zooms in slowly"
|
|
138
|
+
|
|
139
|
+
# 🆕 Batch regenerate (re-roll)
|
|
140
|
+
vibes-api batches regenerate <batch-id> --project-id <id>
|
|
141
|
+
vibes-api batches regenerate <batch-id> --project-id <id> --prompt "new prompt"
|
|
142
|
+
|
|
143
|
+
# 🆕 Ingredient CRUD
|
|
144
|
+
vibes-api ingredients list [--type CHARACTER|STYLE|SETTING]
|
|
145
|
+
vibes-api ingredients create --name "My Character" --type CHARACTER \
|
|
146
|
+
--image-ent-id <id> --image-url <url>
|
|
147
|
+
vibes-api ingredients delete <ingredient_id>
|
|
148
|
+
|
|
149
|
+
# TTS
|
|
150
|
+
vibes-api voices list
|
|
151
|
+
vibes-api tts --voice play_ai_Marisol --text "Hello world" --out hello.mp3
|
|
152
|
+
|
|
153
|
+
# Media library
|
|
154
|
+
vibes-api media list --type video --limit 10
|
|
155
|
+
vibes-api media download --id <id> --out video.mp4
|
|
156
|
+
vibes-api media delete --ids <id1> <id2>
|
|
157
|
+
|
|
158
|
+
# Prompt enhancement
|
|
159
|
+
vibes-api prompts enhance --prompt "a cat"
|
|
160
|
+
|
|
161
|
+
# Share links
|
|
162
|
+
vibes-api share create --entity-type project --entity-id <id>
|
|
163
|
+
vibes-api share list --entity-type project --entity-id <id>
|
|
164
|
+
vibes-api share revoke <share_link_id>
|
|
165
|
+
|
|
166
|
+
# Batches
|
|
167
|
+
vibes-api batches list --project-id <id>
|
|
168
|
+
vibes-api batches get <batch_id>
|
|
169
|
+
vibes-api batches poll <batch_id> --timeout 180
|
|
170
|
+
|
|
171
|
+
# Music
|
|
172
|
+
vibes-api music search --query "lofi"
|
|
173
|
+
|
|
174
|
+
# Timeline AI chat
|
|
175
|
+
vibes-api chat "add a 5 second sunset clip"
|
|
176
|
+
|
|
177
|
+
# 🆕 Real-time sync
|
|
178
|
+
vibes-api sync status --entity-type project --entity-id <id>
|
|
179
|
+
vibes-api sync stream --entity-type project --entity-id <id> # Ctrl+C to stop
|
|
180
|
+
|
|
181
|
+
# 🆕 Quota
|
|
182
|
+
vibes-api quota
|
|
183
|
+
|
|
184
|
+
# End-to-end one-shot
|
|
185
|
+
vibes-api one-shot --prompt "sunset over ocean" --download-dir ./out
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
---
|
|
189
|
+
|
|
190
|
+
## 🎬 Generation flow (under the hood)
|
|
191
|
+
|
|
192
|
+
Vibes uses a **two-step generation pattern**:
|
|
193
|
+
|
|
194
|
+
```
|
|
195
|
+
1) POST /api/generation-batches → create a batch shell (with client-generated UUID v7)
|
|
196
|
+
2) POST /api/generate/videos → trigger actual generation
|
|
197
|
+
3) GET /api/generation-batches/{id} → poll until isComplete=true
|
|
198
|
+
OR /api/generation-batches/{id}/stream (SSE)
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
The client abstracts this away behind `generate_video()` (which polls by default) and `generate_image()` (which is synchronous).
|
|
202
|
+
|
|
203
|
+
### Batch IDs are UUID v7 with `batch-` prefix
|
|
204
|
+
|
|
205
|
+
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:
|
|
206
|
+
- `batch-<uuid_v7>` — normal text/image generation
|
|
207
|
+
- `extend-<timestamp>-<random>` — video extension
|
|
208
|
+
- `image2video-<timestamp>-<random>` — image-to-video (animate)
|
|
209
|
+
- `video2video-<timestamp>-<random>` — video-to-video (edit)
|
|
210
|
+
|
|
211
|
+
### Aspect ratios & resolutions
|
|
212
|
+
|
|
213
|
+
Only **3 aspect ratios** are supported (verified live):
|
|
214
|
+
|
|
215
|
+
| Aspect | Image dimensions | Notes |
|
|
216
|
+
|---|---|---|
|
|
217
|
+
| `1:1` | 1280×1280 | Square |
|
|
218
|
+
| `9:16` | 720×1280 | Portrait (UI default) |
|
|
219
|
+
| `16:9` | 1280×720 | Landscape |
|
|
220
|
+
|
|
221
|
+
Resolutions: `480p` (default, faster) and `720p` (slower but higher quality).
|
|
222
|
+
|
|
223
|
+
### Models
|
|
224
|
+
|
|
225
|
+
| Type | Default model | Description |
|
|
226
|
+
|---|---|---|
|
|
227
|
+
| Image | `midjen-base` | Standard image generation |
|
|
228
|
+
| Video (t2v / i2v) | `midjen-short` | ~5 second clips |
|
|
229
|
+
| **Video extend** | `midjen-extend` | For extending an existing video |
|
|
230
|
+
| **Video edit (v2v)** | `midjen-video-edit` | For re-rendering with a directive |
|
|
231
|
+
| Lip sync | `lipsync` / `midjen-lipsync-async` | Lip-sync generation |
|
|
232
|
+
| Prompt LLM | `gemini-2.5-flash` | Used for prompt enhancement |
|
|
233
|
+
|
|
234
|
+
### Generation types
|
|
235
|
+
|
|
236
|
+
| `generationType` | When to use |
|
|
237
|
+
|---|---|
|
|
238
|
+
| `t2v` | text → video |
|
|
239
|
+
| `t2i` | text → image |
|
|
240
|
+
| `i2v` | image (start frame) → video |
|
|
241
|
+
| `extend` | extend an existing video |
|
|
242
|
+
| `v2v` | video → video (re-render with directive) |
|
|
243
|
+
| `lipsync` | lip-sync generation |
|
|
244
|
+
|
|
245
|
+
---
|
|
246
|
+
|
|
247
|
+
## 🎭 Ingredients (characters, styles, scenes)
|
|
248
|
+
|
|
249
|
+
Vibes supports three ingredient types:
|
|
250
|
+
- **CHARACTER** (UI: "Character") — applies via `orefImageHandle` internally
|
|
251
|
+
- **STYLE** (UI: "Style") — applies via `srefImageHandle` internally
|
|
252
|
+
- **SETTING** (UI: "Scene") — applies via `settingImageHandles` internally
|
|
253
|
+
|
|
254
|
+
There are three ways to reference an ingredient in a generation:
|
|
255
|
+
|
|
256
|
+
```python
|
|
257
|
+
from vibes_api import IngredientType
|
|
258
|
+
from vibes_api.ingredients import IngredientRef, CreateIngredient
|
|
259
|
+
|
|
260
|
+
# 1. By existing ingredient ID (from list_ingredients)
|
|
261
|
+
character = IngredientRef.by_id(
|
|
262
|
+
ingredient_id="800957099700717",
|
|
263
|
+
ingredient_type=IngredientType.CHARACTER,
|
|
264
|
+
name="Valdrin",
|
|
265
|
+
image_url="https://...",
|
|
266
|
+
)
|
|
267
|
+
|
|
268
|
+
# 2. By uploaded image entity ID (creates a new ingredient on-the-fly)
|
|
269
|
+
style = CreateIngredient.by_image_ent_id(
|
|
270
|
+
image_ent_id="1177...",
|
|
271
|
+
ingredient_type=IngredientType.STYLE,
|
|
272
|
+
name="Cyberpunk neon",
|
|
273
|
+
image_url="https://...",
|
|
274
|
+
)
|
|
275
|
+
|
|
276
|
+
# 3. By name only (uses prompt-generated image)
|
|
277
|
+
scene = CreateIngredient.by_name(
|
|
278
|
+
ingredient_type=IngredientType.SETTING,
|
|
279
|
+
name="Misty forest at dawn",
|
|
280
|
+
)
|
|
281
|
+
|
|
282
|
+
# Pass them to generate_video
|
|
283
|
+
batch = client.generate_video(
|
|
284
|
+
project_id=project["id"],
|
|
285
|
+
prompt="...",
|
|
286
|
+
ingredients=[character], # goes in `ingredients[]`
|
|
287
|
+
create_ingredients=[style, scene], # goes in `createIngredients[]`
|
|
288
|
+
)
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
You can also CRUD ingredients directly:
|
|
292
|
+
- `client.list_characters()`, `list_styles()`, `list_scenes()`
|
|
293
|
+
- `client.create_ingredient(name, ingredient_type, source_image_ent_id, ...)`
|
|
294
|
+
- `client.delete_ingredient(ingredient_id)`
|
|
295
|
+
|
|
296
|
+
---
|
|
297
|
+
|
|
298
|
+
## 🖼️ Start/end frame (image-to-video with keyframes)
|
|
299
|
+
|
|
300
|
+
Generate a video that interpolates between two keyframes:
|
|
301
|
+
|
|
302
|
+
```python
|
|
303
|
+
# Generate the start frame image
|
|
304
|
+
start_resp = client.generate_image(
|
|
305
|
+
project_id=project["id"],
|
|
306
|
+
prompt="a rose in full bloom",
|
|
307
|
+
aspect_ratio="16:9",
|
|
308
|
+
)
|
|
309
|
+
# Generate the end frame image
|
|
310
|
+
end_resp = client.generate_image(
|
|
311
|
+
project_id=project["id"],
|
|
312
|
+
prompt="a withered, dried rose",
|
|
313
|
+
aspect_ratio="16:9",
|
|
314
|
+
)
|
|
315
|
+
|
|
316
|
+
# Build frame handles
|
|
317
|
+
start_frame = client.build_frame_handle({
|
|
318
|
+
"mediaEntId": start_resp["data"][0]["imageEntId"],
|
|
319
|
+
"imageUrl": start_resp["data"][0]["url"],
|
|
320
|
+
})
|
|
321
|
+
end_frame = client.build_frame_handle({
|
|
322
|
+
"mediaEntId": end_resp["data"][0]["imageEntId"],
|
|
323
|
+
"imageUrl": end_resp["data"][0]["url"],
|
|
324
|
+
})
|
|
325
|
+
|
|
326
|
+
# Generate the video with both keyframes
|
|
327
|
+
batch = client.generate_video(
|
|
328
|
+
project_id=project["id"],
|
|
329
|
+
prompt="the rose slowly wilts, time-lapse effect",
|
|
330
|
+
start_frame=start_frame,
|
|
331
|
+
end_frame=end_frame,
|
|
332
|
+
aspect_ratio="16:9",
|
|
333
|
+
)
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
For a single start frame (i2v without end frame), just omit `end_frame`.
|
|
337
|
+
|
|
338
|
+
---
|
|
339
|
+
|
|
340
|
+
## 🎥 Video extend (auto + manual)
|
|
341
|
+
|
|
342
|
+
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:
|
|
343
|
+
|
|
344
|
+
```python
|
|
345
|
+
# Get a previously-generated video's full content item
|
|
346
|
+
batch = client.get_batch("batch-...")
|
|
347
|
+
source_video = batch["content"][0]
|
|
348
|
+
|
|
349
|
+
# AUTO extend: no prompt, server continues original
|
|
350
|
+
extended_auto = client.extend_video(
|
|
351
|
+
project_id=project["id"],
|
|
352
|
+
source_video=source_video,
|
|
353
|
+
)
|
|
354
|
+
|
|
355
|
+
# MANUAL extend: provide a directive
|
|
356
|
+
extended_manual = client.manual_extend_video(
|
|
357
|
+
project_id=project["id"],
|
|
358
|
+
source_video=source_video,
|
|
359
|
+
prompt="camera pans up to reveal the sky",
|
|
360
|
+
)
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
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.
|
|
364
|
+
|
|
365
|
+
---
|
|
366
|
+
|
|
367
|
+
## 🔑 Authentication
|
|
368
|
+
|
|
369
|
+
Vibes uses a single cookie, `meta_session`, for authentication. The cookie value is a UUID session token.
|
|
370
|
+
|
|
371
|
+
### How to get your cookie
|
|
372
|
+
|
|
373
|
+
1. Log in at [vibes.ai](https://vibes.ai) in your browser (currently requires a Meta/Facebook account).
|
|
374
|
+
2. Open DevTools (F12) → Application → Cookies → `https://vibes.ai`.
|
|
375
|
+
3. Copy the value of `meta_session` (a long string with a UUID format like `e60e910a-...-K54E`).
|
|
376
|
+
4. Pass it to the client:
|
|
377
|
+
|
|
378
|
+
```python
|
|
379
|
+
client = VibesClient(meta_session="e60e910a-...")
|
|
380
|
+
```
|
|
381
|
+
|
|
382
|
+
Or via env var:
|
|
383
|
+
|
|
384
|
+
```bash
|
|
385
|
+
export VIBES_META_SESSION="e60e910a-..."
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
### Cookie rotation
|
|
389
|
+
|
|
390
|
+
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.
|
|
391
|
+
|
|
392
|
+
### TTS-specific limitation
|
|
393
|
+
|
|
394
|
+
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.
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
398
|
+
## 📡 API endpoint reference
|
|
399
|
+
|
|
400
|
+
All endpoints are under `https://vibes.ai/api/`. This list was extracted directly from the Next.js JS bundles.
|
|
401
|
+
|
|
402
|
+
### Auth & system
|
|
403
|
+
- `GET /api/auth/me` — current user
|
|
404
|
+
- `POST /api/auth/logout` — invalidate session
|
|
405
|
+
- `POST /api/auth/check-token` — token validation
|
|
406
|
+
- `GET /api/system-status` — system status banner
|
|
407
|
+
- `POST /api/analytics` — usage analytics (fire-and-forget)
|
|
408
|
+
- `POST /api/bug-report` — bug reporting
|
|
409
|
+
- `POST /api/consent/record` — cookie consent
|
|
410
|
+
- `GET /api/quota/upsell` — upsell info
|
|
411
|
+
|
|
412
|
+
### Projects
|
|
413
|
+
- `GET /api/projects` — list (params: `limit`, `offset`, `sort`, `search`)
|
|
414
|
+
- `POST /api/projects` — create
|
|
415
|
+
- `GET /api/projects/{id}` — get
|
|
416
|
+
- `PUT /api/projects/{id}` — update name/composition
|
|
417
|
+
- `DELETE /api/projects/{id}?deleteAssets=true` — delete
|
|
418
|
+
- `POST /api/projects/{id}/duplicate` — duplicate
|
|
419
|
+
- `POST /api/projects/{id}/upload` — bulk upload media
|
|
420
|
+
- `GET /api/projects/{id}/batches?limit=6&offset=0` — list batches in project
|
|
421
|
+
- `GET /api/projects/{id}/assets` — list project assets
|
|
422
|
+
- `POST /api/projects/{id}/assets` — add asset
|
|
423
|
+
- `POST /api/projects/{id}/assets/import` — import from another project
|
|
424
|
+
- `GET /api/projects/{id}/assets/available?sourceProjectId={id}` — list importable
|
|
425
|
+
- `POST /api/projects/{id}/timeline/download` — sync export to MP4
|
|
426
|
+
- `POST /api/projects/{id}/timeline/export-surfguard` — start async export
|
|
427
|
+
- `GET /api/projects/{id}/timeline/export/{exportId}/status` — poll export
|
|
428
|
+
- `POST /api/projects/{id}/timeline/export/{exportId}/cancel` — cancel
|
|
429
|
+
|
|
430
|
+
### Generation batches
|
|
431
|
+
- `GET /api/generation-batches?limit=12&offset=0` — list (optional `projectId`, `type`)
|
|
432
|
+
- `POST /api/generation-batches` — create (body must include client-generated UUID v7 as `id`)
|
|
433
|
+
- `GET /api/generation-batches/{id}` — get full state
|
|
434
|
+
- `PUT /api/generation-batches/{id}` — update
|
|
435
|
+
- `DELETE /api/generation-batches/{id}` — delete
|
|
436
|
+
- `GET /api/generation-batches/{id}/stream` — SSE stream of batch updates
|
|
437
|
+
|
|
438
|
+
### Generation
|
|
439
|
+
- `POST /api/generate/videos` — text-to-video, image-to-video, **extend**, **v2v edit**, **image animate** (all via different `type` and `config` values)
|
|
440
|
+
- `POST /api/generate/images` — text-to-image (synchronous)
|
|
441
|
+
- `POST /api/generate/image-edit` — edit an existing image
|
|
442
|
+
- `POST /api/generate/prompts` — prompt enhancement (returns 4 variations)
|
|
443
|
+
- `POST /api/animate/generate` — lip sync / animation
|
|
444
|
+
|
|
445
|
+
### Studio
|
|
446
|
+
- `GET /api/studio/ingredients?ownerFilter=LIBRARY|VIEWER&ingredientType=...` — list ingredients
|
|
447
|
+
- `POST /api/studio/ingredients` — create ingredient
|
|
448
|
+
- `DELETE /api/studio/ingredients/{id}` — delete ingredient
|
|
449
|
+
- `GET /api/studio/voices` — list TTS voices
|
|
450
|
+
- `POST /api/studio/playai/tts` — text-to-speech (body: `{text, voice, outputFormat, language?}`)
|
|
451
|
+
|
|
452
|
+
### Uploads
|
|
453
|
+
- `POST /api/upload-image` — base64 image upload (body: `{image: "<base64>"}`)
|
|
454
|
+
- `POST /api/upload-media` — multipart form (`file` + `filename`)
|
|
455
|
+
- `POST /api/upload-video-direct` — multipart form (`video`)
|
|
456
|
+
- `POST /api/upload-audio-direct` — multipart form (`audio`)
|
|
457
|
+
- `POST /api/upload-profile-picture` — profile picture
|
|
458
|
+
|
|
459
|
+
### Media library & content items
|
|
460
|
+
- `GET /api/media-library?limit=50&offset=0&type=&sort=&search=` — list
|
|
461
|
+
- `GET /api/download/video?id={contentItemId}` — download video MP4
|
|
462
|
+
- `GET /api/download/png?id={contentItemId}` — download image PNG
|
|
463
|
+
- `GET /api/download/{type}?id={id}` — generic download
|
|
464
|
+
- `POST /api/content-items/{id}/favorite` — toggle favorite
|
|
465
|
+
- `POST /api/content-items/{id}/retry` — retry failed item
|
|
466
|
+
- `POST /api/content-items/{id}/feedback` — submit feedback
|
|
467
|
+
- `DELETE /api/content-items/{id}` — delete one
|
|
468
|
+
- `POST /api/content-items/bulk-delete` — bulk delete (body: `{ids: [...]}`)
|
|
469
|
+
|
|
470
|
+
### Audio / music
|
|
471
|
+
- `GET /api/meta-music?q=&limit=&cursor=` — search Meta music library
|
|
472
|
+
- `GET /api/meta-music/lookup?id=&title=` — resolve track thumbnail
|
|
473
|
+
- `POST /api/meta-music/oa-check` — check original audio status
|
|
474
|
+
- `POST /api/media/music/clip` — clip a music track segment
|
|
475
|
+
- `POST /api/media/audio/clip` — clip any audio URL
|
|
476
|
+
- `GET /api/proxy-audio` — proxy audio through Vibes CDN
|
|
477
|
+
- `GET /api/resolve-audio-urls` — resolve audio CDN URLs
|
|
478
|
+
|
|
479
|
+
### Moodboards & playables
|
|
480
|
+
- `GET /api/moodboards` — list
|
|
481
|
+
- `POST /api/moodboards` — create
|
|
482
|
+
- `GET /api/moodboards/{id}` — get
|
|
483
|
+
- `DELETE /api/moodboards/{id}` — delete
|
|
484
|
+
- `GET /api/playables` — list playables (currently disabled: `"Playables not enabled"`)
|
|
485
|
+
|
|
486
|
+
### Timeline AI
|
|
487
|
+
- `POST /api/timeline/chat/stream` — streaming SSE chat (body: `{input, instructions, tools?, composition?}`)
|
|
488
|
+
- Event types: `message_delta`, `message_done`, `tool_call`, `tool_response`, `reasoning_delta`, `reasoning_done`, `completed`, `error`
|
|
489
|
+
- 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`
|
|
490
|
+
|
|
491
|
+
### Share & collaborators
|
|
492
|
+
- `POST /api/share-links` — create (body: `{entityType, entityId, expiresAt?, maxUses?}`)
|
|
493
|
+
- `GET /api/share-links?entityType=&entityId=` — list
|
|
494
|
+
- `DELETE /api/share-links/{id}` — revoke
|
|
495
|
+
- `GET /api/collaborators?entityType=&entityId=` — list
|
|
496
|
+
- `DELETE /api/collaborators/{id}` — remove
|
|
497
|
+
|
|
498
|
+
### 🆕 Real-time sync (SSE)
|
|
499
|
+
- `GET /api/sync?entityType=&entityId=` — get last-updated timestamp
|
|
500
|
+
- `GET /api/sync/stream?entityType=&entityId=` — SSE stream of update events (`snapshot`, `update`, `bye`)
|
|
501
|
+
|
|
502
|
+
### Settings
|
|
503
|
+
- `POST /api/settings/delete-account`
|
|
504
|
+
- `POST /api/settings/delete-all-media`
|
|
505
|
+
- `POST /api/settings/remove-all-posts`
|
|
506
|
+
|
|
507
|
+
### Meta integration
|
|
508
|
+
- `POST /api/meta-graphql` — Meta GraphQL proxy (body: `{doc_id, variables}`)
|
|
509
|
+
- `POST /api/meta-oidc/start` — start OIDC flow
|
|
510
|
+
- `POST /api/meta-profiles/publish` — publish profile
|
|
511
|
+
- `POST /api/revisions` — session revisions
|
|
512
|
+
|
|
513
|
+
---
|
|
514
|
+
|
|
515
|
+
## 🧪 Examples
|
|
516
|
+
|
|
517
|
+
Ten ready-to-run example scripts in [`examples/`](./examples):
|
|
518
|
+
|
|
519
|
+
1. **`01_generate_video.py`** — end-to-end video generation
|
|
520
|
+
2. **`02_images_and_edits.py`** — image generation + editing + media library
|
|
521
|
+
3. **`03_tts_and_lipsync.py`** — TTS → upload → lip sync pipeline
|
|
522
|
+
4. **`04_prompts_and_chat.py`** — prompt enhancement + timeline AI chat
|
|
523
|
+
5. **`05_ingredients.py`** — using saved characters in generations
|
|
524
|
+
6. **`06_extend_video.py`** — 🆕 auto-extend and manual-extend a video
|
|
525
|
+
7. **`07_ingredients_full.py`** — 🆕 character + style + scene combos
|
|
526
|
+
8. **`08_create_ingredient.py`** — 🆕 create a new ingredient via API
|
|
527
|
+
9. **`09_start_end_frame.py`** — 🆕 image-to-video with keyframe interpolation
|
|
528
|
+
10. **`10_edit_video.py`** — 🆕 video-to-video editing (re-render with directive)
|
|
529
|
+
|
|
530
|
+
Run any of them with:
|
|
531
|
+
|
|
532
|
+
```bash
|
|
533
|
+
export VIBES_META_SESSION="..."
|
|
534
|
+
python /home/z/my-project/download/vibes-api/examples/01_generate_video.py
|
|
535
|
+
```
|
|
536
|
+
|
|
537
|
+
---
|
|
538
|
+
|
|
539
|
+
## ⚠️ Limitations & caveats
|
|
540
|
+
|
|
541
|
+
1. **Cookie rotation** — `meta_session` expires. Re-grab from the browser when 401s appear.
|
|
542
|
+
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.
|
|
543
|
+
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.
|
|
544
|
+
4. **No public API** — All endpoints here are private and could change at any time. Pin to a client version if stability matters.
|
|
545
|
+
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.
|
|
546
|
+
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.
|
|
547
|
+
7. **Aspect ratios** — Only `1:1`, `9:16`, `16:9` are supported (server-enforced). Other values return `GENERATION_FAILED`.
|
|
548
|
+
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.
|
|
549
|
+
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.
|
|
550
|
+
10. **Sentry analytics** — The web app posts to Sentry for error tracking. This client does **not** replicate that (it's noise for API use).
|
|
551
|
+
|
|
552
|
+
---
|
|
553
|
+
|
|
554
|
+
## 🛠️ Development
|
|
555
|
+
|
|
556
|
+
```bash
|
|
557
|
+
# Install in editable mode
|
|
558
|
+
pip install -e /home/z/my-project/download/vibes-api
|
|
559
|
+
|
|
560
|
+
# Run tests (requires VIBES_META_SESSION env var)
|
|
561
|
+
pytest
|
|
562
|
+
|
|
563
|
+
# Build CLI
|
|
564
|
+
python -m vibes_api.cli --help
|
|
565
|
+
```
|
|
566
|
+
|
|
567
|
+
### Project layout
|
|
568
|
+
|
|
569
|
+
```
|
|
570
|
+
vibes-api/
|
|
571
|
+
├── pyproject.toml
|
|
572
|
+
├── README.md
|
|
573
|
+
├── QUICKREF.md
|
|
574
|
+
├── TEST_RESULTS.md
|
|
575
|
+
├── vibes_api/
|
|
576
|
+
│ ├── __init__.py # Public API surface
|
|
577
|
+
│ ├── client.py # VibesClient main implementation (~2400 lines, 87 methods)
|
|
578
|
+
│ ├── cli.py # Argparse-based CLI
|
|
579
|
+
│ ├── models.py # Enums: AspectRatio, Resolution, VideoModel, etc.
|
|
580
|
+
│ └── ingredients.py # Ingredient payload builders
|
|
581
|
+
├── examples/
|
|
582
|
+
│ ├── 01_generate_video.py
|
|
583
|
+
│ ├── 02_images_and_edits.py
|
|
584
|
+
│ ├── 03_tts_and_lipsync.py
|
|
585
|
+
│ ├── 04_prompts_and_chat.py
|
|
586
|
+
│ ├── 05_ingredients.py
|
|
587
|
+
│ ├── 06_extend_video.py # 🆕
|
|
588
|
+
│ ├── 07_ingredients_full.py # 🆕
|
|
589
|
+
│ ├── 08_create_ingredient.py # 🆕
|
|
590
|
+
│ ├── 09_start_end_frame.py # 🆕
|
|
591
|
+
│ └── 10_edit_video.py # 🆕
|
|
592
|
+
└── research/
|
|
593
|
+
└── ... (reversing notes, sample responses, screenshots)
|
|
594
|
+
```
|
|
595
|
+
|
|
596
|
+
---
|
|
597
|
+
|
|
598
|
+
## 📜 License
|
|
599
|
+
|
|
600
|
+
MIT. This project is **not affiliated with Meta or Vibes**. Use at your own risk; respect Vibes' Terms of Service.
|