Build · Mobile Try-On

Add virtual try-on to an iOS or Android app

In one sentence

Keep the Photta API key on your backend; expose a proxy endpoint (/mobile/try-on) that accepts the product image and mannequin ID, forwards to /api/v1/tryon/apparel, stores the generation ID against the user, and exposes a status endpoint the mobile app polls every 3 seconds until the image is ready. The phone never learns the Photta key exists.

  • Credits: 5 credits at 2K · 6 credits at 4K
  • Typical time: 1.5–4 min
  • Processing: async, polling

Every figure on this page comes from the Photta API docs · checked

Your device never talks to Photta directly — it talks to your backend, and your backend talks to Photta. That boundary is what keeps your API key off the user's phone, your rate limits your own problem, and your app reviewable on every store.

RESPONSE=$(curl -s -X POST https://api.photta.app/api/v1/tryon/apparel \
  -H "Authorization: Bearer $PHOTTA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "product_type": "top",
  "product_images": [
    "https://cdn.yourstore.com/products/shirt-front.jpg"
  ],
  "product_back_image": "https://cdn.yourstore.com/products/shirt-back.jpg",
  "product_category": "t_shirt",
  "mannequin_id": "mnk_f3a9b1",
  "pose_id": "pose_c2d4e5",
  "background": "https://cdn.yourstore.com/backgrounds/studio-loft.jpg",
  "lock_background": true,
  "resolution": "2K",
  "aspect_ratio": "3:4",
  "body_size": "M",
  "expression": "neutral",
  "user_instruction": "Keep the collar pattern crisp and centered."
}')
ID=$(echo "$RESPONSE" | jq -r '.data.id')

How it works

Device, backend, Photta — three tiers, one flow

Five concrete decisions you need to make before the first App Store submission.

  1. Step 1

    Keep the key on your server

    Do not ship the Photta key inside your app binary, info.plist, AndroidManifest or any build-time env file — decompiling the binary is trivial and the key will leak. Your backend is the only place the key lives.

  2. Step 2

    Design a clean proxy endpoint

    Expose /mobile/try-on to your app. Authenticate the request with your own user session — don't pass raw API keys through the proxy. The proxy then calls Photta on behalf of the authenticated user.

  3. Step 3

    Mirror Photta's job status in your database

    When Photta returns a generation ID, insert a row into your own jobs table keyed by user_id. Your mobile app polls YOUR /mobile/try-on/:id — not Photta's — so rate limits scale with YOUR plan, not each user's device.

  4. Step 4

    Cache the result URL

    When Photta reports completed, copy output_url into your jobs row and optionally download the bytes into your own CDN. Mobile users pay per MB — don't hot-link the Photta CDN for the lifetime of a PDP impression.

  5. Step 5

    Handle offline gracefully

    Mobile networks drop mid-poll. Surface a 'trying again' state rather than a hard error, retry with exponential backoff, and persist the job ID locally so a cold-start picks up where the last session left off.

Three layers of the integration

App contract, backend proxy, client-side polling — the exact boundary you need.

// Never ship your PHOTTA_API_KEY to the device. The mobile app
// calls YOUR API; your API calls Photta. Simple, safe, billable.
POST /mobile/try-on
{
  "productImageUrl": "...",
  "mannequinId": "...",
  "poseId": "..."
}
// → returns { jobId } immediately
const res = await fetch("https://api.photta.app/api/v1/tryon/apparel", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.PHOTTA_API_KEY}`, "Content-Type": "application/json" },
  body: JSON.stringify({
    "product_type": "top",
    "product_images": [
      "https://cdn.yourstore.com/products/shirt-front.jpg"
    ],
    "product_back_image": "https://cdn.yourstore.com/products/shirt-back.jpg",
    "product_category": "t_shirt",
    "mannequin_id": "mnk_f3a9b1",
    "pose_id": "pose_c2d4e5",
    "background": "https://cdn.yourstore.com/backgrounds/studio-loft.jpg",
    "lock_background": true,
    "resolution": "2K",
    "aspect_ratio": "3:4",
    "body_size": "M",
    "expression": "neutral",
    "user_instruction": "Keep the collar pattern crisp and centered."
  }),
});
const { data } = await res.json(); // data.id, data.status
// Store { id: data.id, user_id, status: "processing" } in your jobs table
// and return { jobId: data.id } to the device.
// App polls YOUR /mobile/try-on/:id — you poll Photta server-side
// and mirror status. This way rate limits are YOUR problem, not
// each device's, and you can add caching + analytics in one place.
async function pollJob(jobId: string) {
  while (true) {
    const { status, imageUrl } = await api.get(`/mobile/try-on/${jobId}`);
    if (status === "completed") return imageUrl;
    if (status === "failed") throw new Error("Try-on failed");
    await sleep(3000);
  }
}

Questions developers ask

Shipping a Photta-powered mobile feature

Can I call the Photta API directly from the device?

Technically yes — but you'd have to ship your API key inside the app bundle, which ships your key to every device that installs the app. Route through your own backend so the key stays on a server you control.

How do I handle slow mobile networks?

Two things. One: submit the job from the backend, not the device — you're just uploading a product image from the phone to your own API. Two: poll your own status endpoint with 3-second intervals and an exponential backoff on failure. If the user switches tabs or loses signal, persist the job ID in local storage so they can pick up when they return.

Does Photta support webhooks?

No. Polling is the only completion signal the API offers, so keep the worker loop — and push a server-sent event to the phone the moment your own backend sees the job finish.

Can I use Photta with React Native or Flutter?

Yes — from the JavaScript / Dart side you're just calling your own backend API. None of the Photta specifics bleed through. Flutter apps fetch /mobile/try-on the same way a React Native or native SwiftUI / Jetpack Compose app does.

Does Apple's review team care about this integration?

No — because your app isn't calling Photta. It's calling your own backend with your own auth. From Apple's perspective you're a normal REST-backed app. The same applies to Google Play and Huawei AppGallery.

Ship virtual try-on in your next app release

Three thin layers, zero SDK footprint on the device. Grab an API key and wire the proxy up in an afternoon.