GPT IMAGE 2.5 | WAN 3.0 | SEEDANCE 2.5 IS NOW LIVE!

GENERATE YOUR VIDEOS WITH UNLIMITED SEEDANCE 2.5 TODAY.

NO EXTRA SUBSCRIPTION
REVIRAL
Get API key
Browse API docs

Endpoints

UGC Ad API Quickstart

Was this page helpful?

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.

Keyword target: UGC ad API

The UGC ad endpoint turns one product photo 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. Every request requires an Idempotency-Key so a timeout can be retried without starting a duplicate paid job.

  1. Upload the product photo with POST /api/v1/uploads and retain the returned uploadId. A remote productImageUrl is not accepted.
  2. Read GET /api/v1/ugc-ad/options, then call calculate-credits with kind ugc-ad and the same settings before choosing maxCredits.
  3. 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","creator":"lifestyle","scene":"home","singleClip":true,"mode":"r2v","durationSec":15,"resolution":"720p","aspectRatio":"9:16","maxCredits":40,"webhookUrl":"https://example.com/reviral/jobs"}'
Example response
{
  "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.
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.
POST

/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","creator":"lifestyle","scene":"home","singleClip":true,"mode":"r2v","durationSec":15,"resolution":"720p","aspectRatio":"9:16","maxCredits":40,"webhookUrl":"https://example.com/reviral/jobs"}'

Request body

FieldTypeRequiredDescription
uploadIdstringYesOwned id returned by POST /api/v1/uploads.
promptstringYes
anglestring: testimonial | unboxing | before-after | problem-solution | founder | day-in-lifeYes
creatorstring: skincare | lifestyle | fitness | techYes
scenestring: home | kitchen | cafe | deskYes
singleClipbooleanNo
modestring: i2v | r2vNo
durationSecinteger: 15 | 30 | 45 | 60No
resolutionstring: 480p | 720p | 1080pNo
aspectRatiostring: 9:16 | 16:9 | 1:1No
maxCreditsinteger (min 0)No
webhookUrlstringNo

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