Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 3 additions & 8 deletions .agents/skills/pixverse-growth-studio-api/SKILL.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,12 +26,7 @@ npm run cli -- growth-studio --help

Growth Studio uses `PIXVERSE_GROWTH_API_KEY` and bearer authentication. It must not read `PIXVERSE_PLATFORM_API_KEY` or use Platform credits. Keep keys in `.env` or the server environment, never in a payload, command argument, artifact, or browser.

Optional folder configuration for the existing URL-based workflow:

```bash
PIXVERSE_GROWTH_FOLDER_API_PREFIX=/marketing_hub
PIXVERSE_GROWTH_FOLDER_API_KEY=...
```
Folders use the documented `GET`/`POST /openapi/v1/folders` endpoints with the same `PIXVERSE_GROWTH_API_KEY`; no separate folder credential exists. A folder is targeted with the string `video.folder_id` inside the create payload, never a top-level `folder_id`.

A non-loopback custom origin must be HTTPS, explicitly enabled with `PIXVERSE_GROWTH_ALLOW_CUSTOM_BASE_URL=true`, and controlled by the operator.

Expand Down Expand Up @@ -84,8 +79,8 @@ For a local image, upload it first and place only the returned `https://media.pi
Folder targeting applies only to the existing general workflow:

- `--folder-id <folder_id>` uses a verified folder.
- `--folder-name <name>` reuses a case-insensitive match or creates the folder.
- `--auto-folder` infers a folder from supported general-payload fields.
- `--folder-name <name>` reuses an exact (trimmed) name match or creates the folder with that name unchanged.
- `--auto-folder` infers a normalized folder name from supported general-payload fields and reuses a case-insensitive match.

Prefer `growth-studio run-job` over direct general-video creation when a durable artifact trail is needed. General-video creation has no dry-run mode.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,4 +49,4 @@ Use `resource.templates`, `resource.tts-speakers`, and `resource.restyle-effects
- [Rate limits](https://docs.platform.pixverse.ai/rate-limit-796040m0)
- [Image upload](https://docs.platform.pixverse.ai/upload-image-13016631e0)
- [Video and audio upload](https://docs.platform.pixverse.ai/upload-videoaudio-19094401e0)
- [One-Click Music MV interface](https://aisphere.feishu.cn/wiki/L8pgwGoSwiDbQ8ksGIHcppcvnrc)
- [One-click VibeMV](https://docs.platform.pixverse.ai/one-click-vibemv-44175576e0)
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Every documented Platform API endpoint currently covered by `pixverse-api platfo
| operation:resource.restyle-effects | `platform resource restyle-effects` | GET | `/openapi/v2/video/restyle/list` | read-only | no | none | Live page filters before choosing `restyle_id` | https://docs.platform.pixverse.ai/restyle-effect-list-21992862e0 |
| operation:voice.create | `platform voice create` | POST | `/openapi/v2/video/tts_speaker` | non-billable | no | none | Voice name plus uploaded audio `media_id` string | https://docs.platform.pixverse.ai/create-custom-voice-40528181e0 |
| operation:voice.delete | `platform voice delete` | DELETE | `/openapi/v2/video/tts_speaker/{speaker_id}` | non-billable | no | none | Known custom `speaker_id` string | https://docs.platform.pixverse.ai/delete-custom-voice-40528243e0 |
| operation:image.template | `platform image template` | POST | `/openapi/v2/image/template/generate` | billable | yes | `Resp.image_id` | Uploaded `img_ids` strings plus live `template_id` | https://docs.platform.pixverse.ai/image-template-generation-27564921e0 |
| operation:image.template | `platform image template` | POST | `/openapi/v2/image/template/generate` | billable | yes | `Resp.image_id` | Uploaded `img_ids` plus live `template_id` | https://docs.platform.pixverse.ai/image-template-generation-27564921e0 |
| operation:image.status | `platform image status` | GET | `/openapi/v2/image/result/{image_id}` | read-only | no | `Resp.image_id` | Known `image_id` string; never resubmit generation to poll | https://docs.platform.pixverse.ai/get-image-generation-27565028e0 |
| operation:video.text | `platform video text` | POST | `/openapi/v2/video/text/generate` | billable | yes | `Resp.video_id` | Prompt plus compatible model/duration/quality/aspect ratio | https://docs.platform.pixverse.ai/text-to-video-generation-13016634e0 |
| operation:video.image | `platform video image` | POST | `/openapi/v2/video/img/generate` | billable | yes | `Resp.video_id` | Uploaded `img_id` string plus prompt/model/duration/quality | https://docs.platform.pixverse.ai/image-to-video-generation-13016633e0 |
Expand All @@ -26,13 +26,13 @@ Every documented Platform API endpoint currently covered by `pixverse-api platfo
| operation:video.restyle | `platform video restyle` | POST | `/openapi/v2/video/restyle/generate` | billable | yes | `Resp.video_id` | Source video plus live `restyle_id` | https://docs.platform.pixverse.ai/restyle-video-generation-21992681e0 |
| operation:video.swap-mask | `platform video swap-mask` | POST | `/openapi/v2/video/mask/selection` | billable | no | none | Source video plus safe-integer-string `keyframe_id` | https://docs.platform.pixverse.ai/swap-mask-generation-24001877e0 |
| operation:video.swap | `platform video swap` | POST | `/openapi/v2/video/swap/generate` | billable | yes | `Resp.video_id` | Source video, keyframe/mask from mask selection, replacement `img_id`, and quality | https://docs.platform.pixverse.ai/swap-video-generation-24001839e0 |
| operation:video.sound-effect | `platform video sound-effect` | POST | `/openapi/v2/video/sound_effect/generate` | billable | yes | `Resp.video_id` | Source video plus sound description | https://docs.platform.pixverse.ai/sound-effect-generation-19884196e0 |
| operation:video.sound-effect | `platform video sound-effect` | POST | `/openapi/v2/video/sound_effect/generate` | billable | yes | `Resp.video_id` | Source video plus optional `sound_effect_content` description | https://docs.platform.pixverse.ai/sound-effect-generation-19884196e0 |
| operation:video.extend | `platform video extend` | POST | `/openapi/v2/video/extend/generate` | billable | yes | `Resp.video_id` | Source video plus continuation prompt and compatible V6 fields | https://docs.platform.pixverse.ai/extend-generation-19094393e0 |
| operation:video.motion-control | `platform video motion-control` | POST | `/openapi/v2/video/mimic/generate` | billable | yes | `Resp.video_id` | Motion source video plus subject `img_id` and quality | https://docs.platform.pixverse.ai/motion-control-mimic-generation-28748523e0 |
| operation:video.modify | `platform video modify` | POST | `/openapi/v2/video/modify/generate` | billable | yes | `Resp.video_id` | Source video plus edit prompt; optional masks/references | https://docs.platform.pixverse.ai/modify-generation-33365578e0 |
| operation:video.upscale | `platform video upscale` | POST | `/openapi/v2/video/upscale/generate` | billable | yes | `Resp.video_id` | Exactly one Platform-generated `source_video_id` or uploaded `video_media_id` | https://docs.platform.pixverse.ai/upscale-video-37938008e0 |
| operation:video.avatar | `platform video avatar` | POST | `/openapi/v2/video/avatar/generate` | billable | yes | `Resp.video_id` | Portrait `img_id` plus quality and exactly one uploaded-audio or TTS source | https://docs.platform.pixverse.ai/avatar-generation-40528034e0 |
| operation:agent.viral-recreation | `platform agent viral-recreation` | POST | `/openapi/v2/video/agent/generate` | billable | yes | `Resp.video_id` | Fixed agent ID, prompt, image references, and exactly one video reference | https://docs.platform.pixverse.ai/viral-recreation-agent-41205382e0 |
| operation:agent.real-estate | `platform agent real-estate` | POST | `/openapi/v2/video/agent/generate` | billable | yes | `Resp.video_id` | Fixed agent ID/model plus listing URL or supported image set | https://docs.platform.pixverse.ai/one-click-real-estate-video-42843647e0 |
| operation:agent.music-mv | `platform agent music-mv` | POST | `/openapi/v2/video/music_mv_agent/generate` | billable | yes | `Resp.video_id` | Verified audio plus optional character/style image references | https://aisphere.feishu.cn/wiki/L8pgwGoSwiDbQ8ksGIHcppcvnrc |
| operation:agent.music-mv | `platform agent music-mv` | POST | `/openapi/v2/video/music_mv_agent/generate` | billable | yes | `Resp.video_id` | Verified audio plus optional character/style image references | https://docs.platform.pixverse.ai/one-click-vibemv-44175576e0 |
| operation:video.status | `platform video status` | GET | `/openapi/v2/video/result/{video_id}` | read-only | no | `Resp.id` | Known `video_id` string; never resubmit generation to poll | https://docs.platform.pixverse.ai/get-video-generation-status-13016632e0 |
Original file line number Diff line number Diff line change
Expand Up @@ -200,7 +200,7 @@
"description": "Generate synchronized sound for an existing video.",
"input": {
"source_video_id": "629000000000000005",
"prompt": "Gentle rain and distant thunder."
"sound_effect_content": "Gentle rain and distant thunder."
}
},
"video.extend": {
Expand Down Expand Up @@ -258,7 +258,7 @@
"img_id": "629000000000000001",
"quality": "720p",
"lip_sync_tts_speaker_id": "speaker-7",
"lip_sync_tts_content": "Here is the latest update."
"lip_sync_tts_content": "Here is the latest product update for this week."
}
}
]
Expand All @@ -271,12 +271,12 @@
"quality": "720p",
"img_references": [
{
"img_url": "https://cdn.example.test/reference.png"
"img_id": "629000000000000002"
}
],
"video_references": [
{
"video_url": "https://cdn.example.test/reference.mp4"
"video_media_id": "629000000000000005"
}
]
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,9 @@ HTTP success is not Platform success. Require a valid response envelope and `Err
| Provider parameter rejection | Nonzero parameter-related `ErrCode` | Compare the specialized example, local validator, and current endpoint page; change only the rejected input. |
| Moderation | Status 7 or moderation `ErrCode` | Treat as terminal. Report the provider reason; revise content only if the user asks. Do not hide or bypass moderation. |
| Rate/concurrency pressure | Rate/concurrency `ErrCode`, HTTP 429, or retry guidance | For read-only calls, wait as directed and retry safely. For a confirmed-not-accepted submission, follow provider guidance; if acceptance is ambiguous, reconcile instead of resubmitting. |
| Polling issue | Transient failure while a result ID is known | Preserve the ID and job directory; resume polling without recreating the generation. |
| Polling issue | Transient failure while a result ID is known | Status polling already waits through transport errors, HTTP 429/5xx, and `500069`/`500044` until its timeout (see `poll_error` records in `polling.jsonl`). After a timeout, preserve the ID and job directory and resume polling without recreating the generation. |
| High load (`500069`) | Provider reports the system is under high load | Retryable for read-only calls; status polling continues automatically. A submission rejected with it was not accepted; obtain fresh approval before submitting again, and never auto-resubmit. |
| Webhook duplicates | PixVerse redelivers until it receives `ok` | The handler acknowledges verified duplicates (same nonce, or same `id` and `status`) with `ok` and does not call the delivery callback twice. A `409` means the first attempt is still in progress. |
| Ambiguous billable submission | Timeout/connection loss after dispatch and no saved result ID | Do not retry or resubmit. Keep `request.json` and trace ID, inspect usage/provider records, and report `reconciliation_required`. |
| Terminal generation failure | Status 6, 7, or 8 | Preserve final status, trace, provider envelope, and failure details; do not automatically create a replacement job. |
| Missing result ID | Successful-looking create envelope lacks the cataloged ID path | Preserve create response and trace; stop as a response-contract error and reconcile. |
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,14 @@ Platform billable commands wait for a terminal result by default. To return imme

`image_references` is accepted as a documented input alias and normalized to `img_references`. Do not send both fields. Lip sync requires recognizable vocals; audio verification does not authorize an automatic paid submission.

Keep Music MV identifiers as decimal strings in payload files and artifacts. The request layer losslessly serializes the documented `uint64` fields (`audio_media_id` and reference `img_id` values) as JSON number tokens because the live verification and generation endpoints reject quoted identifiers.
Keep identifiers as decimal strings in payload files and artifacts. The request layer losslessly serializes every field an operation's API reference types as integer, plus fusion `video_references` IDs and `image.template` `img_ids`, which the schemas list as string but the live API only accepts as integers (for example `img_id`, `img_ids`, `template_id`, `source_video_id`, `video_media_id`, `audio_media_id`, `keyframe_id`, `restyle_id`, `agent_id`, and reference `img_id` values) as JSON number tokens, because the endpoints reject quoted identifiers with ErrCode 400013. Fields the reference types as string (`mask_id`, `mask_ids`, `lip_sync_tts_speaker_id`, `webhook_id`) stay quoted.

### Durable artifact meanings

- `request.json` is written before submission and records the provider, operation, redacted headers, original submission trace, and normalized input.
- `create-response.json` preserves the redacted create response.
- `video-id.json` or `image-id.json` preserves the known result ID as a string.
- `polling.jsonl` appends each redacted status snapshot and status-request trace.
- `polling.jsonl` appends each redacted status snapshot and status-request trace, plus a `poll_error` record for each transient status-read failure.
- `final.json` preserves the original submission `trace_id`; `status_trace_id` identifies the latest status request.
- `error.json` preserves safe failure classification and trace context without exposing secrets.

Expand All @@ -67,10 +67,14 @@ Keep Music MV identifiers as decimal strings in payload files and artifacts. The

Poll a known ID at the documented cadence and honor provider retry guidance. Preserve the original submission trace separately from status-request traces.

The default cadence is 5 seconds with a 30 minute wait per session; a timeout is resumable. Transient status-read failures (transport errors, HTTP 429/5xx, `ErrCode` `500069` high load or `500044` concurrency limit) do not fail the job: polling backs off, honors `Retry-After`, and continues until the overall timeout. Other read errors fail immediately. Every read-only retry uses a fresh `Ai-trace-id`. The billable submission is never retried automatically.

## Webhooks

Use the [official webhook page](https://docs.platform.pixverse.ai/how-to-use-webhook-1905378m0) to confirm current supported operations and delivery behavior. Verify timestamp, nonce, Base64 HMAC-SHA256 signature, time window, and nonce replay state before parsing JSON or invoking delivery logic. Return plain `ok` only after verified successful handling; use HTTPS and idempotent delivery processing.

PixVerse resends until it receives `ok` (8 retries over about 5 hours). The built-in handler therefore answers a verified duplicate (same nonce, or same payload `id` and `status` with a fresh nonce) with `200 ok` without invoking the delivery callback again, and answers `409` only while the first attempt is still in progress. `null` payload values are accepted (signed as `null`). The timestamp window defaults to 6 hours (`timestampToleranceSeconds`) so PixVerse's own late retries are not rejected if they reuse the original timestamp; nonce and `(id, status)` deduplication still block replays.

## Raw diagnostics

Use `platform raw` only for a relative `/openapi/v2/` path when diagnosing a documented endpoint or inspecting a newly published endpoint not yet in the catalog. Start with `--dry-run`. Never pass API keys, cookies, host, content length, authorization, or trace headers; the CLI owns those headers and assigns a fresh trace.
Expand Down
3 changes: 0 additions & 3 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,3 @@ PIXVERSE_GROWTH_API_KEY=mh_live_REPLACE_WITH_PRODUCTION_API_KEY
PIXVERSE_GROWTH_BASE_URL=https://growth-api.pixverse.ai
# Required only for a non-official, non-loopback HTTPS origin:
# PIXVERSE_GROWTH_ALLOW_CUSTOM_BASE_URL=true
# Optional, only if Growth Studio folder list/create uses a different API prefix/token:
# PIXVERSE_GROWTH_FOLDER_API_PREFIX=/marketing_hub
# PIXVERSE_GROWTH_FOLDER_API_KEY=REPLACE_WITH_FOLDER_MANAGEMENT_TOKEN
2 changes: 0 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -158,8 +158,6 @@ PIXVERSE_PLATFORM_BASE_URL=https://app-api.pixverse.ai

PIXVERSE_GROWTH_API_KEY=mh_live_...
PIXVERSE_GROWTH_BASE_URL=https://growth-api.pixverse.ai
PIXVERSE_GROWTH_FOLDER_API_PREFIX=/marketing_hub
PIXVERSE_GROWTH_FOLDER_API_KEY=...
```

Keys stay server-side. Platform and Growth Studio credentials are separate and never fall back to each other.
Expand Down
Loading
Loading