Skip to main content

API Documentation

Would rather not write an integration? The try-on widget installs with a single <script> tag on your storefront — no backend, no API calls.

Install the widget →

Authentication

Pass your API key in the X-Api-Key. Keys start with the prefix tn_live_.

X-Api-Key: tn_live_xxxxxxxxxxxxxxxx

Credit Model

Every B2B feature deducts credits from your current-period quota at submission time. Credits are auto-refunded on permanent failure — no manual action required.

FeatureCredit formula
Try-On1 credit per call
Description1 credit per call
Model Shootvariants × 3 + (2 if generated model) + (1 if custom background)
Videoper duration: 5s = 1, 8s = 2, 10s = 3, 15s = 4 (admin-managed)
Try-On Videoper duration: 5s = 1, 8s = 2, 10s = 3, 15s = 4 (separate tryon_video balance)

Refunds: permanent provider failure → full auto-refund; transient (internally retried) → no refund; model-shoot QA failure → non-refunding (a generation occurred).

Image Upload

POST /api/v1/b2b/uploads/ — multipart upload of one image (field file; JPEG, PNG or WebP, max 10 MB). Costs no credits. Returns an upload_id (pass as garment_upload_id) and a public url (usable as any *_image_url). You need this because every submit endpoint accepts only public HTTPS URLs — with this you no longer have to host images yourself. The id stops resolving after expires_in seconds.

curl -X POST https://api.try-nova.shop/api/v1/b2b/uploads/ \
  -H "X-Api-Key: tn_live_..." \
  -F "file=@garment.jpg"

# => { "data": { "upload_id": "9f2c...", "url": "https://...", "expires_in": 900 } }
# Pass upload_id as garment_upload_id, or use url as garment_image_url.

Pose & Background Catalogue

GET /api/v1/b2b/public/presets/ — no auth required. Returns the valid pose_preset_ids and background_preset values with preview cards and labels. Fetch these rather than hardcoding them: the catalogue changes, and an unknown id is a 400. Query params: locale (ru/en) and gender (male returns the male pose set; backgrounds are gender-agnostic).

# No API key needed — this is a public catalogue.
curl "https://api.try-nova.shop/api/v1/b2b/public/presets/?locale=en&gender=female"

# => { "data": { "version": 3, "gender": "female",
#      "poses":       [{ "id": "front_full", "label": "Front", "image_url": "..." }, ...],
#      "backgrounds": [{ "id": "studio_white", "label": "White studio", ... }, ...] } }

Your Own Models (saved models)

POST /api/v1/b2b/models/generate/ — mint a model to your spec (async; charges the generate surcharge, default 2 credits). Poll GET /api/v1/b2b/models/jobs/{request_id}/, then pass model.uuid as saved_model_id with model_source="saved" — reuse after that is free. List them with GET /api/v1/b2b/models/. This is also the answer when the stock library has no model of the type you need.

# 1. Generate a model (async, charges the generate surcharge once)
curl -X POST https://api.try-nova.shop/api/v1/b2b/models/generate/ \
  -H "X-Api-Key: tn_live_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"gender":"male","ethnicity":"south_asian","body_type":"athletic","age_range":"25-30","name":"Hero model"}'

# 2. Poll until status is "completed"
curl https://api.try-nova.shop/api/v1/b2b/models/jobs/<request_id>/ \
  -H "X-Api-Key: tn_live_..."

# 3. Reuse the model.uuid on any shoot or video — free from here on
curl -X POST https://api.try-nova.shop/api/v1/b2b/model-shoot/ \
  -H "X-Api-Key: tn_live_..." -H "Content-Type: application/json" \
  -d '{"garment_image_url":"https://...","model_source":"saved","saved_model_id":"<uuid>","model_gender":"male","pose_preset_ids":["front_full"],"variant_count":1}'

Virtual Try-On (VTO)

POST /api/v1/b2b/tryon/ — submit a try-on task. output_format=image (1 credit) or output_format=video (animated clip; charged from the separate tryon_video balance by duration — pass video_duration_seconds and motion_type). Use Idempotency-Key to prevent duplicates. Status: GET /api/v1/b2b/tryon/{request_id}/ (result_image_url is the VTO frame/poster, result_video_url is the finished video).

# Image output (1 credit)
curl -X POST https://api.try-nova.shop/api/v1/b2b/tryon/ \
  -H "X-Api-Key: tn_live_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: unique-request-id" \
  -d '{"body_image_url":"https://...","garment_image_url":"https://..."}'

# Video output (charged from the tryon_video balance by duration)
curl -X POST https://api.try-nova.shop/api/v1/b2b/tryon/ \
  -H "X-Api-Key: tn_live_..." \
  -H "Content-Type: application/json" \
  -d '{"body_image_url":"https://...","garment_image_url":"https://...","output_format":"video","video_duration_seconds":8,"motion_type":"turn"}'

Product Description Generation

POST /api/v1/b2b/tools/description/ — generate an SEO product description (1 credit). Supports Wildberries, Ozon, etc.

curl -X POST https://api.try-nova.shop/api/v1/b2b/tools/description/ \
  -H "X-Api-Key: tn_live_..." \
  -H "Content-Type: application/json" \
  -d '{"product_name":"Denim Jacket","product_attributes":{"color":"blue","size":"M"},"platform":"wildberries"}'

Model Shoot — Generate model photoshoot

POST /api/v1/b2b/model-shoot/ — generate product images on a model. Cost: variants × 3 + 2 (if model_source=generate) + 1 (if background_custom_url). Status: GET /api/v1/b2b/model-shoot/{request_id}/.

# You need a saved_model_id first — see "Your Own Models" above.
# model_source "stock" is retired and returns 400 STOCK_MODELS_UNAVAILABLE.
# pose_preset_ids must be DISTINCT and its length must equal variant_count;
# fetch valid pose/background ids from /api/v1/b2b/public/presets/.
curl -X POST https://api.try-nova.shop/api/v1/b2b/model-shoot/ \
  -H "X-Api-Key: tn_live_..." \
  -H "Content-Type: application/json" \
  -d '{"garment_image_url":"https://...","model_source":"saved","saved_model_id":"<uuid>","model_gender":"female","model_ethnicity":"european","model_body_type":"average","model_age_range":"25-30","background_preset":"studio_white","pose_preset_ids":["front_full","three_quarter","profile","walking"],"lighting_preset":"studio_softbox","variant_count":4}'

Video Generation

POST /api/v1/b2b/video/ — generate an ad video. Supported durations and credit cost are admin-managed (defaults: 5s=1, 8s=2, 10s=3, 15s=4). Status: GET /api/v1/b2b/video/{request_id}/.

curl -X POST https://api.try-nova.shop/api/v1/b2b/video/ \
  -H "X-Api-Key: tn_live_..." \
  -H "Content-Type: application/json" \
  -d '{"garment_image_url":"https://...","model_gender":"female","duration_seconds":8,"aspect_ratio":"9:16"}'

Analytics & tracking

1. Add the tracking pixel

After you integrate the generation API, embed this once on every storefront page that shows a TryNova asset:

<script src="https://pixel.try-nova.shop/pixel.js" data-key="YOUR_PIXEL_KEY"></script>

Mark each rendered asset with the request_id you received at generation time:

<div data-trynova-asset="REQUEST_ID" data-trynova-sku="YOUR_SKU"> …asset… </div>

Consent: the pixel stores nothing and sends nothing until consent is granted. Either add data-consent="granted" to the script tag, or call TryNova.consent() after your own cookie/consent banner is accepted (TryNova.revoke() opts out). Impressions and views are then tracked automatically. Fire intent events yourself:

TryNova.track("add_to_cart", { assetId: "REQUEST_ID", sku: "YOUR_SKU" });

Purchases and returns are not sent from the browser (the pixel key is public) — see step 2.

2. Send purchases & returns server-side (required for revenue)

The pixel key is public — it's visible in your page source — so it can only send low-trust events (impressions / views / add-to-cart). Purchases and returns carry money, so they must come from your backend with a secret API key, never the pixel key:

curl -X POST https://api.try-nova.shop/api/v1/b2b/events/ \
  -H "X-Api-Key: YOUR_SECRET_KEY" -H "Content-Type: application/json" \
  -d '{"event_id":"order-1234","asset_id":"REQUEST_ID","sku":"YOUR_SKU","event_type":"purchase","value":4990,"currency":"RUB","occurred_at":"2026-06-23T12:00:00Z"}'

Include a stable event_id (e.g. your order id) so retries are idempotent. Use "event_type":"return" when an order is returned.

3. Read the report

Events roll up into an impression → view → cart → purchase funnel and land on the Sales analytics page in your dashboard. The dashboard reads three endpoints — authenticated with the dashboard JWT, not an API key: summary/ (funnel and KPIs), by-product/ (per-SKU breakdown, paginated) and roas/?spend=... (revenue over the ad spend you enter).

# Same numbers the Sales analytics page renders.
# Dashboard JWT — the X-Api-Key credential does NOT open these read endpoints.
curl "https://api.try-nova.shop/api/v1/b2b/dashboard/analytics/summary/?days=30" \
  -H "Authorization: Bearer <dashboard JWT>"

{
  "success": true,
  "data": {
    "impressions": 12480, "views": 3120, "add_to_carts": 468,
    "purchases": 187, "returns": 13, "revenue": 933130,
    "view_rate": 0.25, "add_to_cart_rate": 0.15,
    "conversion_rate": 0.0599, "return_rate": 0.0695,
    "currency": "RUB",
    "deltas": { "conversion_rate": 0.008, "revenue": 121400 }
  }
}

# Per-SKU rows (paginated) — sku comes from data-trynova-sku on the asset.
curl ".../analytics/by-product/?days=30" -H "Authorization: Bearer <jwt>"
{ "count": 42, "next": "...", "results": [
    { "sku": "DRS-114-BLK", "views": 910, "add_to_carts": 148,
      "purchases": 63, "returns": 4, "revenue": 314370,
      "conversion_rate": 0.0692 } ] }

Sample 30-day report

Conversion
6.0%
Return rate
7.0%
Revenue
933 130 ₽
ROAS
7.8×
Impressions12,480
Views3,120
Add to cart468
Purchases187

The rollup runs nightly and ends at yesterday, so today's events aren't in the report yet. deltas compare against the prior window of equal length — they are not try-on lift.

4. Selling on a marketplace (Wildberries / Ozon / Amazon)?

The pixel can't run on marketplace listing pages, so storefront analytics won't cover those sales yet. Connecting your marketplace account to read per-SKU views, orders, and returns is coming soon (a separate release).

Error Codes

CodeHTTPDescription
QUOTA_EXCEEDED429Request quota exceeded or balance depleted
VALIDATION_ERROR400Invalid request parameters
FIELD_NOT_SUPPORTED400Field was removed from the API (e.g. camera_angles, scene_vibe) — drop it
IDEMPOTENCY_CONFLICT409Idempotency-Key reused with a different request body
PROVIDER_ERROR502Third-party AI provider error
NOT_FOUND404Resource not found