> ## Documentation Index
> Fetch the complete documentation index at: https://docs.yourproducthere.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# End-to-end workflow

> Digital Sample seed upload, actor, Insta Swap, and result retrieval.

This guide walks through the main API integration path: sample → seed → actor → insta swap → result.

## 1. Create a Digital Sample

```bash theme={null}
curl -s -X POST "$BASE_URL/digital-samples" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Summer SKU demo",
    "description": "API-created sample"
  }'
```

Save `sample.id` from the response.

## 2. Upload seed video

### Option A — Presigned PUT

```bash theme={null}
# Request upload URL
curl -s -X POST "$BASE_URL/digital-samples/SAMPLE_ID/seed/upload-url" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "contentType": "video/mp4", "contentLength": 5242880 }'
```

PUT your file to `uploadUrl`, then associate it with the sample using the single-step register endpoint. The public API automatically validates, approves, and activates the sample in one go (no legacy commit step required):

```bash theme={null}
curl -s -X POST "$BASE_URL/digital-samples/SAMPLE_ID/seed/register" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "key": "seed-assets/…" }'
```

The response includes `signedSeedVideoUrl` for preview. There is no external `seedVideoUrl` echo for this upload path (you uploaded directly).

### Option B — External HTTPS URL

On create or PATCH, pass `seedVideoUrl` with a public HTTPS link. YPH ingests the file into private storage:

```bash theme={null}
curl -s -X PATCH "$BASE_URL/digital-samples/SAMPLE_ID" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "seedVideoUrl": "https://your-cdn.example.com/seed.mp4" }'
```

The response echoes your `seedVideoUrl` and adds `signedSeedVideoUrl` for preview. **Do not** send `signedSeedVideoUrl` back on PATCH.

## 3. Create an Actor

Provide **public HTTPS URLs** for face, body, and voice assets. YPH securely ingests them into private storage. The response echoes your source URLs plus short-lived `signed*AssetUrl` fields for preview:

```bash theme={null}
curl -s -X POST "$BASE_URL/actors" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "displayName": "Alex",
    "faceAssetUrl": "https://your-cdn.example.com/face.jpg",
    "bodyAssetUrl": "https://your-cdn.example.com/body.jpg",
    "voiceClipUrl": "https://your-cdn.example.com/voice.mp3"
  }'
```

Use `signedFaceAssetUrl`, `signedBodyAssetUrl`, and `signedVoiceClipUrl` from the response to download or verify ingested assets. **Do not** send those signed URLs back on PATCH — only send new external HTTPS URLs when updating assets.

## 4. Queue Insta Swap

```bash theme={null}
curl -s -X POST "$BASE_URL/digital-samples/SAMPLE_ID/insta-swaps" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "actorId": "ACTOR_ID" }'
```

The job is **auto-queued** (`autoQueue: true`). One credit is charged by default.

Response includes `instaSwap.id` and initial `status` (typically `QUEUED`).

## 5. Poll for completion

```bash theme={null}
curl -s "$BASE_URL/insta-swaps/SWAP_ID" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

When `instaSwap.status` is `COMPLETED`, the response may include `instaSwap.signedResultVideoUrl` — a short-lived presigned GET URL for the output video.

## 6. Webhooks (recommended)

Register once per environment:

```bash theme={null}
curl -s -X POST "$BASE_URL/webhooks" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-server.com/yph",
    "events": ["insta_swap.queued", "insta_swap.completed", "insta_swap.failed"]
  }'
```

See [Webhooks](/webhooks) for signature verification.

## Status reference

Insta Swap jobs use render pipeline statuses, including:

* `QUEUED` — waiting for GPU capacity
* `ASSIGNED` / `RENDERING` — in progress
* `COMPLETED` — success
* `FAILED` — terminal error

Poll `GET /insta-swaps/{id}` or rely on webhook `data.status`.
