Endpoints
UGC Ad API Quickstart
Start a UGC ad API job from an owned product upload, preview its credit quote, require safe retry protection, and poll or receive the finished video.
By Wilson Sik Founder, Reviral Last updated
Keyword target: UGC ad API
The UGC ad endpoint turns one product photo, a presenter and a creative brief into a complete UGC-style video job. It accepts uploadId only: first upload the image through the API, then send the returned owned ID. The presenter is required: a ready preset from the options endpoint or your own face photo, sent the same way as the product photo. Every request requires an Idempotency-Key so a timeout can be retried without starting a duplicate paid job.
- Upload the product photo with POST /api/v1/uploads and retain the returned uploadId. A remote productImageUrl is not accepted.
- Read GET /api/v1/ugc-ad/options, then call calculate-credits with kind ugc-ad and the same settings before choosing maxCredits.
- Pick the presenter: presenter.preset (a ready presenter id from the options endpoint) or presenter.uploadId (your own face photo, uploaded with POST /api/v1/uploads). Send exactly one; a missing presenter is a 400 and nothing is charged.
- POST the request with a unique Idempotency-Key. Reuse that exact key only with the exact same body when retrying a timeout, then poll statusUrl or process the terminal webhook.
Working example
Set REVIRAL_API_KEY only in your server environment, then run this request with values valid for your account.
curl -X POST "https://reviral.ai/api/v1/ugc-ad" \
-H "Authorization: Bearer $REVIRAL_API_KEY" \
-H "Idempotency-Key: first-generation" \
-H "Content-Type: application/json" \
--data '{"uploadId":"up_01HPRODUCT","prompt":"A candid commuter discovers the bottle never leaks in a packed tote.","angle":"problem-solution","scene":"home","presenter":{"preset":"550e8400-e29b-41d4-a716-446655440001"},"singleClip":true,"mode":"r2v","durationSec":15,"resolution":"720p","aspectRatio":"9:16","maxCredits":40,"webhookUrl":"https://example.com/reviral/jobs"}'{
"data": {
"jobId": "550e8400-e29b-41d4-a716-446655440000",
"kind": "ugc-ad",
"creditsCharged": 40,
"status": "queued",
"statusUrl": "/api/v1/jobs/550e8400-e29b-41d4-a716-446655440000"
}
}Frequently asked questions
- Can I send a product image URL to the UGC ad API?
- No. Send uploadId from POST /api/v1/uploads so the product image is owned and checked for the authenticated account.
- Can the ad use my own face photo as the presenter?
- Yes. Upload the photo with POST /api/v1/uploads and send its uploadId as presenter.uploadId. Or pick a ready presenter: send presenter.preset with an id from GET /api/v1/ugc-ad/options. Send exactly one.
- Is Idempotency-Key optional for UGC ads?
- No. The header is required. Reuse it with the unchanged body after a timeout to recover the first job response safely.
- How do I know the UGC ad price before starting?
- Call POST /api/v1/calculate-credits with kind ugc-ad and the same generation settings. The quote does not start or debit a render.
/api/v1/ugc-ad
Start a UGC ad
Requires Idempotency-Key, quotes with the account's current rate, enforces maxCredits, then starts the shared UGC workflow. After a timeout, retry with the same Idempotency-Key.
Authentication: Bearer API key required
curl -X POST "https://reviral.ai/api/v1/ugc-ad" \
-H "Authorization: Bearer $REVIRAL_API_KEY" \
-H "Idempotency-Key: first-generation" \
-H "Content-Type: application/json" \
--data '{"uploadId":"up_01HPRODUCT","prompt":"A candid commuter discovers the bottle never leaks in a packed tote.","angle":"problem-solution","scene":"home","presenter":{"preset":"550e8400-e29b-41d4-a716-446655440001"},"singleClip":true,"mode":"r2v","durationSec":15,"resolution":"720p","aspectRatio":"9:16","maxCredits":40,"webhookUrl":"https://example.com/reviral/jobs"}'Request body
| Field | Type | Required | Description |
|---|---|---|---|
| uploadId | string | Yes | Owned id returned by POST /api/v1/uploads. |
| prompt | string | Yes | — |
| angle | string: testimonial | unboxing | before-after | problem-solution | founder | day-in-life | Yes | — |
| creator | string: skincare | lifestyle | fitness | tech | No | Optional. Kept for older integrations. |
| scene | string: home | kitchen | cafe | desk | Yes | — |
| presenter | object | Yes | Who is on camera. Send exactly one: preset (a ready presenter id from GET /api/v1/ugc-ad/options) or uploadId (your own face photo, uploaded with POST /api/v1/uploads; jpg, png or webp). |
| singleClip | boolean | No | — |
| mode | string: r2v | No | — |
| durationSec | integer: 15 | 30 | 45 | 60 | No | — |
| resolution | string: 480p | 720p | 1080p | No | — |
| aspectRatio | string: 9:16 | 16:9 | 1:1 | No | — |
| maxCredits | integer (min 0) | No | — |
| webhookUrl | string | No | — |
Responses
- 202
- UGC ad accepted or idempotently replayed
- 400
- Body is empty or is not JSON
- 401
- Key is missing, revoked, or invalid
- 402
- Account needs more credits
- 409
- Either the live charge changed (price_changed) or the Idempotency-Key was already used with a different request body (idempotency_key_reuse)
- 422
- Settings are invalid or a reference field is unsupported
- 429
- Too many requests
- 502
- Job could not be started
- 503
- Models or rate limiting are temporarily unavailable