# Account usage analytics Source: https://docs.yourproducthere.ai/api-reference/account/account-usage-analytics /openapi.yaml get /account/analytics Job counts for your organization, grouped by channel (`app` = platform UI, `api` = Public API). Actor Swap counts are completed/failed Insta Swap render jobs. Media Variations counts are seed analyze and variation propose jobs. Operational telemetry (tokens, Cloud Run) is not exposed here. # Organization account Source: https://docs.yourproducthere.ai/api-reference/account/organization-account /openapi.yaml get /account Credit balance and API access flag for the key's organization. # Create actor Source: https://docs.yourproducthere.ai/api-reference/actors/create-actor /openapi.yaml post /actors Create a new custom actor with a display name and optional URLs for face, body, or voice clip assets. # Delete actor Source: https://docs.yourproducthere.ai/api-reference/actors/delete-actor /openapi.yaml delete /actors/{id} Permanently remove an actor from your organization. # List actors Source: https://docs.yourproducthere.ai/api-reference/actors/list-actors /openapi.yaml get /actors # Update actor Source: https://docs.yourproducthere.ai/api-reference/actors/update-actor /openapi.yaml patch /actors/{id} Update the attributes or asset URLs of an existing actor. All fields in the body are optional. # Assemble variation MP4 Source: https://docs.yourproducthere.ai/api-reference/digital-samples/assemble-variation-mp4 /openapi.yaml post /digital-samples/{id}/variations/{variationId}/assemble FFmpeg cut from seed using the variation edit timeline. Required before the variation is selectable for render. # Create digital sample Source: https://docs.yourproducthere.ai/api-reference/digital-samples/create-digital-sample /openapi.yaml post /digital-samples Create a new digital sample in draft mode or actively initialized with a seed video. # Delete digital sample Source: https://docs.yourproducthere.ai/api-reference/digital-samples/delete-digital-sample /openapi.yaml delete /digital-samples/{id} Permanently delete a digital sample and cascade-remove its insta-swap render jobs. Deletes associated R2 seed video objects (`seed-assets/…`) and render results (`results/{jobId}/result.mp4`). Blocked with `409 Conflict` when collaborators exist on the sample. # Enable or disable a variation for Collab / Insta Swap Source: https://docs.yourproducthere.ai/api-reference/digital-samples/enable-or-disable-a-variation-for-collab-insta-swap /openapi.yaml patch /digital-samples/{id}/variations/{variationId} # Get digital sample Source: https://docs.yourproducthere.ai/api-reference/digital-samples/get-digital-sample /openapi.yaml get /digital-samples/{id} Retrieve a single digital sample by its unique UUID. # Get seed video analysis Source: https://docs.yourproducthere.ai/api-reference/digital-samples/get-seed-video-analysis /openapi.yaml get /digital-samples/{id}/analysis Forensic metadata and render risk summary for the uploaded seed. # List digital samples Source: https://docs.yourproducthere.ai/api-reference/digital-samples/list-digital-samples /openapi.yaml get /digital-samples Retrieve all active (non-archived) digital samples for your organization. Use query filters for embed/widget scoping. # List selectable seeds for render Source: https://docs.yourproducthere.ai/api-reference/digital-samples/list-selectable-seeds-for-render /openapi.yaml get /digital-samples/{id}/available-seeds Enabled original (if ≤30s) and assembled variations with `selectable` flags. # List variation proposals Source: https://docs.yourproducthere.ai/api-reference/digital-samples/list-variation-proposals /openapi.yaml get /digital-samples/{id}/variations # Mint presigned seed upload URL Source: https://docs.yourproducthere.ai/api-reference/digital-samples/mint-presigned-seed-upload-url /openapi.yaml post /digital-samples/{id}/seed/upload-url Get a secure presigned R2 PUT URL to upload your seed video directly. # Propose more variations Source: https://docs.yourproducthere.ai/api-reference/digital-samples/propose-more-variations /openapi.yaml post /digital-samples/{id}/variations/propose # Register uploaded seed key Source: https://docs.yourproducthere.ai/api-reference/digital-samples/register-uploaded-seed-key /openapi.yaml post /digital-samples/{id}/seed/register Associate your uploaded seed video key with the digital sample. Under the public API, this endpoint performs an asynchronous validation of the uploaded file's format and duration, automatically approves it, and activates the sample. # Toggle original seed for creators Source: https://docs.yourproducthere.ai/api-reference/digital-samples/toggle-original-seed-for-creators /openapi.yaml patch /digital-samples/{id}/seed-options # Update digital sample Source: https://docs.yourproducthere.ai/api-reference/digital-samples/update-digital-sample /openapi.yaml patch /digital-samples/{id} Update configuration, prompts, advanced render parameters, or title/description of an existing digital sample. All fields in the body are optional. **Seed Video Replacement Policy:** If `seedVideoUrl` is provided, it replaces the current seed video. Note that replacing the seed video of a digital sample with active collaborations is blocked (returns `409 Conflict`) to safeguard operational consistency. If a seed video is successfully replaced, any existing unlinked or old seed video is safely replaced in the database. On an **ACTIVE** sample, replacing the seed may demote the sample to `DRAFT` and disable collab/public flags until the new seed is re-validated. # Create and queue insta swap Source: https://docs.yourproducthere.ai/api-reference/insta-swaps/create-and-queue-insta-swap /openapi.yaml post /digital-samples/{id}/insta-swaps Auto-queues a render task to replace the sample seed's identity with the specified custom actor. Automatically processes and charges 1 credit. Pass `digitalSampleVariationId` to render an assembled variation cut; use `null` for the original seed when eligible (≤30s and enabled). # Get insta swap status Source: https://docs.yourproducthere.ai/api-reference/insta-swaps/get-insta-swap-status /openapi.yaml get /insta-swaps/{id} Retrieve the real-time status and telemetry of an individual insta swap task. Once the status transitions to COMPLETED, includes a temporary short-lived `signedResultVideoUrl` that is valid for 1 hour. # List insta swaps for a sample Source: https://docs.yourproducthere.ai/api-reference/insta-swaps/list-insta-swaps-for-a-sample /openapi.yaml get /digital-samples/{id}/insta-swaps Retrieve insta swaps for a digital sample. Pass `accountToken` to scope results to a creator or brand (embed widgets require a token). # Health check Source: https://docs.yourproducthere.ai/api-reference/system/health-check /openapi.yaml get /health # Create webhook endpoint Source: https://docs.yourproducthere.ai/api-reference/webhooks/create-webhook-endpoint /openapi.yaml post /webhooks Register a new webhook endpoint. When `verify` is true (default), YPH sends a synchronous `webhook.test` post request to verify endpoint readiness and reachability before creation. # Delete webhook endpoint Source: https://docs.yourproducthere.ai/api-reference/webhooks/delete-webhook-endpoint /openapi.yaml delete /webhooks/{id} Deregister and permanently remove a webhook endpoint. No further events will be delivered to this URL. # List recent deliveries Source: https://docs.yourproducthere.ai/api-reference/webhooks/list-recent-deliveries /openapi.yaml get /webhooks/{id}/deliveries Retrieve the delivery logs and dispatch history (up to last 50 attempts) for a specific webhook endpoint. # List webhook endpoints Source: https://docs.yourproducthere.ai/api-reference/webhooks/list-webhook-endpoints /openapi.yaml get /webhooks Retrieve all configured webhook endpoints and available subscription event types for your organization. # Authentication Source: https://docs.yourproducthere.ai/authentication API keys, Bearer headers, and environment prefixes. All authenticated routes require: ```http theme={null} Authorization: Bearer ``` ## Key format | Environment | Prefix | Example | | ----------- | -------------- | --------------------- | | Production | `yph_sk_live_` | `yph_sk_live_a1b2c3…` | Keys are tied to your organization. The key hash is stored server-side; the full secret is shown only when created or regenerated in **Developer**. ## Obtaining a key To generate a programmatic API key: **API Activation Required**\ API access is disabled for organizations by default. You must contact Michel ([michel@yourproducthere.ai](mailto:michel@yourproducthere.ai)) to enable API access for your organization before proceeding. 1. Once API access is enabled by Michel, sign in to [Your Product Here](https://yourproducthere.ai). 2. Open [**Developer**](https://yourproducthere.ai/app/developer) in your sidebar. 3. Click **Regenerate API key**. 4. Copy the key prefix and token immediately — it will not be shown again. You can view the active key **prefix** anytime in Developer; use it to identify which key is in use without exposing the secret. ## Security practices * Store keys in a secrets manager (never in client-side code or public repos). * Use your keys securely against the production API base URL. * Rotate keys from Developer if a key may have leaked; old keys stop working immediately. ## Unauthorized responses ```json theme={null} { "error": "Unauthorized" } ``` HTTP `401` — invalid or missing Bearer token. ```json theme={null} { "error": "api_access_disabled", "code": "API_ACCESS_DISABLED" } ``` HTTP `403` — org exists but API access was not enabled by admin. ## Public routes Only `GET /health` is unauthenticated. # Enterprise API installation & asset quality (beta) Source: https://docs.yourproducthere.ai/guides/enterprise-installation Onboarding checklist, integration steps, and current asset constraints for best render quality. **Beta constraints** — validation rules and quality recommendations on this page reflect the **current** Public API and render pipeline. We tighten and relax limits as the product matures. Check `updatedAt` on this page and the [changelog in OpenAPI](/api-reference/health) when you upgrade integrations. This guide is for **enterprise / platform integrators** after API access is enabled. It complements the [workflow guide](/guides/workflow) with onboarding steps and **asset preparation** rules that match the YPH app upload UI and server validators today. ## 1. Request access & install credentials API access is **off by default**. Email [michel@yourproducthere.ai](mailto:michel@yourproducthere.ai?subject=Enterprise%20API%20activation%20-%20YPH%20AI) with your org name and integration use case. Sign in at [yourproducthere.ai](https://yourproducthere.ai), open [**Developer**](https://yourproducthere.ai/app/developer), and regenerate your key (`yph_sk_live_…`). Store it in a secrets manager — the full secret is shown **once**. Production base: `https://api.yourproducthere.ai/v1`. Keep this site ([docs.yourproducthere.ai](https://docs.yourproducthere.ai)) and [`llms.txt`](/llms.txt) in your repo for AI-assisted integration. ```bash theme={null} curl -s https://api.yourproducthere.ai/v1/health curl -s https://api.yourproducthere.ai/v1/account \ -H "Authorization: Bearer YOUR_API_KEY" ``` Expect `apiAccessEnabled: true` and a credit balance on `/account`. Partner diligence: [Company credentials](https://yourproducthere.ai/credentials) · [Enterprise use case](https://yourproducthere.ai/use-cases/enterprise-b2b-api) ## 2. Integration order (canonical) Follow this order on every environment — skipping steps causes `400`/`404`/`409` errors: 1. `POST /digital-samples` (draft or with external `seedVideoUrl`) — set `accountToken` (brand) and optional `productToken` for enterprise embeds 2. Seed video — presigned `upload-url` → PUT → `register`, **or** HTTPS ingest via `seedVideoUrl` 3. `POST /actors` (face + body + voice URLs) — set `accountToken` (creator or brand) 4. `POST /digital-samples/{id}/insta-swaps` (charges **1 credit** on queue) — optional `accountToken` on swap (defaults from actor) 5. Poll `GET /insta-swaps/{id}` or register `POST /webhooks` for `insta_swap.*` See [Integrator tokens](/guides/integrator-tokens) for brand vs creator scoping and `isBrandSelfService`. Details: [End-to-end workflow](/guides/workflow) · [Integrator tokens](/guides/integrator-tokens) · [Authentication](/authentication) · [Webhooks](/webhooks) ## 3. Digital Sample seed video Seed quality drives Insta Swap output. The API and app enforce the same **hard limits**; the app also shows **soft warnings** for best results. ### Hard limits (API rejects or deletes object) | Rule | Value | Error / behavior | | ---------------------- | --------------------------------------------------- | ---------------------------------------------------------------------------------- | | Container | **MP4** or **MOV** (`video/mp4`, `video/quicktime`) | `seed_mp4_or_mov_required` / ingest failure | | Duration | **≤ 30 seconds** | `video_too_long` / `video duration exceeds maximum allowed 30 seconds` | | File size | **≤ 80 MB** (83,886,080 bytes) | Presign `400`; ingest deletes oversize object | | `seedVideoDurationSec` | **≤ 30** when sent in JSON | `400` validation | | Aspect (strict UI) | **9:16 vertical** required in app wizard | App blocks continue if not vertical | | Aspect (API ingest) | 9:16 recommended | Non–9:16 may **warn** (`not_vertical_9_16`) on register; API path may still accept | | Source URL | Public **HTTPS** (no localhost / private IPs) | Ingest `400` | | Replace seed | Blocked if sample has **active collaborations** | `409 seed_replace_blocked_collaborations` | Workers cannot run ffprobe. Duration and aspect are parsed from ISO BMFF (`moov`/`tkhd`) when possible. If metadata is unreadable (e.g. `moov` at end of file), the API may accept the file with a `dimensions_unparsed` warning — **re-export with “fast start” / web-optimized MP4** for reliable validation. ### Safe-shot checklist (beta — from product UI) For best likeness and fewer failed renders, seed content should: * Show **only one person** on camera * Avoid biting food, outfit changes, or applying products on camera * Match the **SKU/listing** you will attach in Collab flows * Avoid scripts that instruct affiliates to claim personal use (“I tried”, “my honest review”, etc.) * Include only media you **own or have rights** to (people, product, music) ### Upload paths | Method | When to use | | --------------------------------------------------------------- | ----------------------------------------------------------------- | | **Presigned PUT** (`/seed/upload-url` + PUT + `/seed/register`) | You control the file bytes; best for DAM/PIM pipelines | | **HTTPS `seedVideoUrl`** on create/PATCH | YPH fetches and ingests from your CDN; must be publicly reachable | After ingest, use **`signedSeedVideoUrl`** in API responses to preview the private copy — never send signed URLs back on PATCH. ## 4. Actor assets (face, body, voice) Provide **HTTPS URLs** on `POST /actors` or `PATCH /actors/{id}`. YPH ingests into private R2 and returns echo source URLs plus short-lived `signed*AssetUrl` fields. ### Face & body images | Rule | Value | | ------------------ | ------------------------------------------------------------- | | Formats | **JPEG, PNG, WebP** | | Max size | Face **12 MB**, body **15 MB** | | Recommended export | **480 × 832 px**, **9:16** portrait (matches render workflow) | | Minimum source | At least **480 × 832** so we never upscale a tiny crop | OpenAPI and responses may include non-blocking `warnings` (e.g. dimensions below 480×832). **Export exactly 480×832** from your asset pipeline for maximum quality. ### Voice clip | Rule | Value | | -------- | ---------------------------------------- | | Formats | **MP3, WAV, OGG** | | Max size | **10 MB** | | Duration | **10–30 seconds** of clean speech | | Content | Single speaker, minimal background noise | ## 5. Render parameters (Digital Sample) Set on create or PATCH. Invalid combinations return `400`. | Field | Allowed values | Notes | | ------------------------------ | ---------------------- | ------------------------------------------------------------------ | | `renderSeedFps` | **16**, **24**, **30** | Default **16**. Higher FPS = better motion/lip sync, more GPU time | | `renderEntryWidth` | **480**, **720** | Portrait **9:16** analysis size; default **480** | | `renderVoiceConversionEnabled` | boolean | When `true`, replace seed audio with actor voice via CosyVoice | In the YPH app, **30 FPS** with closest face match may be blocked on seeds **longer than 25 seconds** (hardware guardrail). Prefer **24 FPS** or shorter seeds for premium tiers until this limit is lifted in a future release. ## 6. Insta Swap & webhooks * Each queued swap costs **1 credit** (see `GET /account`). * Poll `GET /insta-swaps/{id}` until `status` is terminal, or use webhooks (`insta_swap.queued`, `insta_swap.completed`, `insta_swap.failed`). * Result video: `signedResultVideoUrl` (short-lived presigned GET). ## 7. Errors vs warnings | Type | Meaning | Action | | ------------------------------------ | ----------------------------------------------- | -------------------------------------------- | | **HTTP 4xx** + `error` / `parameter` | Hard validation failure | Fix input; object may be deleted from R2 | | **`warnings[]` on Actor** | Quality hint; request succeeded | Improve assets; re-upload optional | | **`warning` on seed register (app)** | e.g. `not_vertical_9_16`, `dimensions_unparsed` | Re-export recommended; API may still proceed | ## 8. AI-assisted development Point Cursor, Claude, or Copilot at: * [`llms.txt`](/llms.txt) — skills context with bounds and workflow order * [OpenAPI reference](/api-reference/health) — schemas and examples * This page — **human-readable beta constraints** ## 9. Versioning We update this guide when validation or quality bars change. Integrators should: 1. Watch commits under `mintlify/` in the monorepo 2. Re-run your staging conformance / Contract run after upgrades 3. Treat `warnings` as forward-compatible hints; treat new **4xx** codes as breaking for automation Questions or activation: [michel@yourproducthere.ai](mailto:michel@yourproducthere.ai) # Integrator identity tokens Source: https://docs.yourproducthere.ai/guides/integrator-tokens Opaque accountToken and productToken fields for enterprise embed widgets and multi-brand orgs. Enterprise integrators (MCNs, marketplaces, creative automation platforms) run **one YPH org** and map many brands and creators using opaque tokens from **their** database. YPH does not create child orgs per advertiser or creator. ## Fields | Field | Resource | Meaning | | -------------- | -------------- | ------------------------------------------------------------- | | `accountToken` | Digital sample | **Brand** id in your system | | `productToken` | Digital sample | Optional **catalog product** id (SKU/listing key) | | `accountToken` | Actor | **Creator** id, or **brand** id when the brand owns the actor | | `accountToken` | Insta swap | Who initiated the swap — copied from the actor by default | `productToken` is **not** the same as `productUrl` (public TikTok Shop / listing URL used in Collab). Use `productToken` for your internal product primary key. All tokens are optional strings, max **128** characters, scoped to your org. Pass `null` on PATCH to clear. ## Widget filtering rule Embed UIs should **require** an `accountToken` from your session (brand dashboard or creator app). List endpoints accept `?accountToken=`: * `GET /digital-samples?accountToken=brand_nike` * `GET /digital-samples?accountToken=brand_nike&productToken=sku_123` * `GET /actors?accountToken=creator_42` * `GET /digital-samples/{id}/insta-swaps?accountToken=creator_42` **Without a token, widgets should show no rows** — your integrator decides which token to inject per surface. Server-to-server calls with your API key may omit filters and see the full org. ## Brand self-service vs creator application Compare the swap token with the parent sample's brand token: | Sample `accountToken` | Swap `accountToken` | Mode | | --------------------- | ------------------- | --------------------------------------------------------------- | | `brand_nike` | `creator_42` | **Creator application** — different parties | | `brand_nike` | `brand_nike` | **Brand self-service** — brand creates its own actors and swaps | The API exposes this on insta swap responses as read-only `isBrandSelfService` (`true` when tokens match). Typical setup: 1. **Brand** creates sample with `accountToken: "brand_nike"` and optional `productToken`. 2. **Creator** creates actor with `accountToken: "creator_42"`, then `POST …/insta-swaps` with that actor (swap stores `creator_42`). 3. **Brand** approval widgets list swaps where `sampleAccountToken` is the brand token and `accountToken` differs (creator applications). Brand production widgets list resources where `accountToken` equals the brand token on samples, actors, and swaps. ## Examples ### Create a brand-scoped sample ```bash theme={null} curl -s https://api.yourproducthere.ai/v1/digital-samples \ -H "Authorization: Bearer $YPH_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "title": "Nike Air Max — winning format", "accountToken": "brand_nike", "productToken": "sku_air_max_90", "seedVideoUrl": "https://cdn.example.com/seeds/nike.mp4" }' ``` ### Create a creator actor ```bash theme={null} curl -s https://api.yourproducthere.ai/v1/actors \ -H "Authorization: Bearer $YPH_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "displayName": "Michel", "accountToken": "creator_42", "faceAssetUrl": "https://cdn.example.com/creators/face.jpg", "voiceClipUrl": "https://cdn.example.com/creators/voice.mp3" }' ``` ### Queue a creator swap (tokens differ → not self-service) ```bash theme={null} curl -s https://api.yourproducthere.ai/v1/digital-samples/$SAMPLE_ID/insta-swaps \ -H "Authorization: Bearer $YPH_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "actorId": "'"$ACTOR_ID"'", "accountToken": "creator_42" }' ``` Response includes `sampleAccountToken`, `productToken`, and `isBrandSelfService: false`. ## Security note `accountToken` values are **identifiers**, not secrets. Never embed your `yph_sk_*` API key in client-side widgets. Phase-2 embed tokens will scope widget calls to a single token and resource set. ## Related * [Enterprise installation](/guides/enterprise-installation) * [End-to-end workflow](/guides/workflow) * [OpenAPI schemas](/api-reference/digital-samples/list-digital-samples) # End-to-end workflow Source: https://docs.yourproducthere.ai/guides/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`. # Introduction Source: https://docs.yourproducthere.ai/introduction Programmatic access to Digital Samples, Actors, Insta Swaps, and webhooks on Your Product Here. The YPH Public API lets your systems create **Digital Samples**, manage **Actors**, queue **Insta Swaps**, and receive **webhooks** — without using the Collab UI. **Integrating with AI?** If you are using ChatGPT, Claude, GitHub Copilot, Cursor, or any other AI assistant to build your integration, just feed them our [**AI Integration Skills Context (`/llms.txt`)**](/llms.txt) file. This gives the AI the exact API specifications, strict parameters, validation limits, and step-by-step workflow requirements so it can write your integration code instantly and accurately. ## Base URLs | Environment | Base URL | | ----------- | ----------------------------------- | | Production | `https://api.yourproducthere.ai/v1` | Your base API origin is managed and provided by YPH. After activation, your org's base URL and curl examples appear on the in-app **Developer** page. ## What you can build * Sync actors and digital samples from your PIM or DAM * Upload seed videos via presigned URLs or direct HTTP/HTTPS links (automatic secure R2 stream-ingest) * Queue face-replacement renders and poll for results * Subscribe to `insta_swap.*` events instead of email ## What is not in scope (today) * Collab, marketplace, or proof-of-post flows * Self-serve account creation (`POST /v1/accounts`) * Email notifications for API-enabled orgs (use webhooks) ## Getting access The YPH Public API is restricted to approved enterprise integration partners. Programmatic access is locked by default — you cannot self-serve API keys. **Request API activation** — contact Michel at [michel@yourproducthere.ai](mailto:michel@yourproducthere.ai) to enable API access for your organization and configure your API domain. Once your organization has been approved and activated: 1. Sign in to [Your Product Here](https://yourproducthere.ai). 2. Open the **Developer** page in your sidebar. 3. Generate your API key (`yph_sk_live_…`). API keys are shown in full only once at creation/regeneration. Store them securely in your secrets manager. ## Next steps Onboarding, beta asset rules, and quality checklist. Health check, account, and first authenticated call. Bearer tokens and key prefixes. Signed events and endpoint verification. OpenAPI-generated endpoint docs. # Quickstart Source: https://docs.yourproducthere.ai/quickstart Verify connectivity and make your first authenticated API request. ## Prerequisites **API Access is Locked**\ programmatic access is locked by default. Before you can make any authenticated calls, **you must contact Michel ([michel@yourproducthere.ai](mailto:michel@yourproducthere.ai)) to enable API access for your organization**. * API access enabled for your organization (by contacting Michel) * An API key from **Developer** in the app (`yph_sk_live_…`) * Your environment base URL (see [Introduction](/introduction)) **Building with an AI Copilot?** You can copy our [**AI Integration Skills Context (`/llms.txt`)**](/llms.txt) and paste it directly into your AI prompt (or attach it as a file). It is fully optimized to tell LLMs exactly how our video upload, actor creation, and Insta Swap rendering flows operate. Replace `BASE_URL` and `YOUR_API_KEY` in the examples below. ## 1. Health check (no auth) ```bash theme={null} curl -s "$BASE_URL/health" ``` Expected response: ```json theme={null} { "ok": true, "service": "yph-api", "env": "production" } ``` ## 2. Account and credits ```bash theme={null} curl -s "$BASE_URL/account" \ -H "Authorization: Bearer YOUR_API_KEY" ``` Expected response: ```json theme={null} { "orgId": "…", "creditBalance": 10, "apiAccessEnabled": true } ``` ## 3. List actors ```bash theme={null} curl -s "$BASE_URL/actors" \ -H "Authorization: Bearer YOUR_API_KEY" ``` ## Typical integration flow `POST /digital-samples` with title and render prompts. `POST /digital-samples/{id}/seed/upload-url` → PUT file to presigned URL → `POST …/seed/register` (automatically validates, approves, and activates the sample). Upload face/body/voice assets via your app workflow or presigned URLs, then `POST /actors`. `POST /digital-samples/{id}/insta-swaps` with `actorId`. Render starts automatically; credits are charged. `GET /insta-swaps/{id}` until `status` is terminal, or handle `insta_swap.completed` / `insta_swap.failed` webhooks. See [End-to-end workflow](/guides/workflow) for detail. ## Errors | HTTP | Meaning | | ----- | ------------------------------------ | | `401` | Missing or invalid API key | | `403` | `api_access_disabled` for the org | | `402` | `insufficient_credits` on insta-swap | | `404` | Resource not found or wrong org | | `422` | Webhook URL failed verification | # Webhooks Source: https://docs.yourproducthere.ai/webhooks Subscribe to Insta Swap lifecycle events with signed HTTPS POSTs. API-enabled organizations receive **webhooks** instead of email when Insta Swaps change state. Manage endpoints in the app (**Developer → Webhooks**) or via `POST /webhooks`. ## Events | Event | When | | ----------------------------------- | --------------------------------------------------------------- | | `insta_swap.queued` | Job entered the render queue | | `insta_swap.completed` | Render finished; result available | | `insta_swap.failed` | Render failed | | `digital_sample.analysis.completed` | Forensic video analysis finished; variation proposals drafted | | `digital_sample.analysis.failed` | Forensic video analysis failed | | `webhook.test` | Verification or manual test ping (not stored as a subscription) | **Webhook events ≠ Insta Swap `status`.** A swap moves through many pipeline states (`QUEUED`, `ASSIGNED`, `RENDERING`, `PENDING_APPROVAL`, `COMPLETED`, `FAILED`, `EXPIRED`, `CANCELLED`) visible on `GET /insta-swaps/{id}`. Public webhooks only fire at three integration milestones — queued, completed, and failed — so partners are not flooded with intermediate GPU/render updates. Mid-flight progress is for polling, not subscription. ## Create an endpoint ```bash theme={null} curl -s -X POST "$BASE_URL/webhooks" \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com/webhooks/yph", "events": ["insta_swap.completed", "insta_swap.failed"], "verify": true }' ``` When `verify` is `true` (default), YPH sends `webhook.test` before saving. Your URL must respond with **HTTP 2xx**. On success, the response includes a **signing secret** (shown once): ```json theme={null} { "endpoint": { "id": "…", "url": "https://example.com/webhooks/yph", "events": ["insta_swap.completed", "insta_swap.failed"], "secret": "…", "enabled": true } } ``` ## Payload shape ```json theme={null} { "event": "insta_swap.completed", "idempotencyKey": "insta_swap.completed:job-uuid", "createdAt": "2026-06-20T12:00:00.000Z", "data": { "jobId": "…", "digitalSampleId": "…", "actorId": "…", "status": "COMPLETED" } } ``` ## Verify signatures Each delivery includes: | Header | Value | | ----------------------- | -------------- | | `X-YPH-Event` | Event name | | `X-YPH-Idempotency-Key` | Dedup key | | `X-YPH-Signature` | `sha256=` | Compute the signature: ``` signature = SHA256( secret + ":" + raw_request_body ) ``` Compare to `X-YPH-Signature` (strip the `sha256=` prefix). Use constant-time comparison in production. Reject requests with invalid signatures. The secret is only returned at endpoint creation. ## List and delete ```bash theme={null} curl -s "$BASE_URL/webhooks" -H "Authorization: Bearer YOUR_API_KEY" curl -s -X DELETE "$BASE_URL/webhooks/ENDPOINT_ID" -H "Authorization: Bearer YOUR_API_KEY" ``` Delivery history: `GET /webhooks/{id}/deliveries`. ## Retries Failed deliveries are retried with exponential backoff (up to 3 attempts). Check `last_error` in delivery records for debugging.