Try-On Pipeline

Try-On Pipeline

The storefront try-on is asynchronous: create a session, kick off a provider task, the provider calls back, the client polls for the result.

Storefront flow

  1. SessionPOST /api/storefront/session { shopDomain, productHandle } → creates a tryon_sessions row, checks widget-enabled access, returns a server sessionId + product snapshot (incl. primary reference image URL).
  2. Try-onPOST /api/storefront/try-on { shopDomain, productHandle, sessionId, personImageDataUrl }:
    • Billing gate (checkBillingGate), IP abuse limit (enforceAuditWindowLimit), per-shopper rate limit (with email-gate bonus).
    • Resolve product + primary garment image.
    • Persist the person image (persistInputImageTRYVIO_STORAGE_INPUT_BUCKET).
    • createTryOnProviderClient(...).createTryOnTask({ personImageUrl, garmentImageUrl, callBackUrl }) → provider task id stored in tryon_provider_jobs.
    • Returns { status: 'pending', pollAfterMs }.
  3. Callback — the provider calls /api/storefront/try-on/callback (signed token) when done; the output is persisted (persistOutputImage → output bucket).
  4. Status — client polls POST /api/storefront/try-on-status { sessionId, … } → returns { status, outputImageUrl? } once succeeded.

Why async

generateTryOn (the synchronous variant) polls the provider until complete (~60–90s), which exceeds serverless limits. Production uses createTryOnTask + provider callback + client polling instead.

Storage buckets

Env varBucket
TRYVIO_STORAGE_INPUT_BUCKETuploaded person images (short retention)
TRYVIO_STORAGE_OUTPUT_BUCKETgenerated results
TRYVIO_STORAGE_MERCHANT_BUCKETmerchant-provided images

The storage-cleanup cron expires old input/output rows after TRYVIO_TEMP_FILE_MAX_AGE_HOURS.

Result hosting note

KIE.AI returns result URLs on tempfile.aiquickdraw.com; fal.ai on fal.media/cdn.fal.ai. The app persists outputs to Supabase Storage for durability.