Build · AI Photography SaaS
Build an AI product photography service
In one sentence
Provision a Photta API key per tenant (or pool if volume is small), fan out over each customer's catalog into a queue, call /api/v1/tryon/apparel per product, poll the generation IDs in a worker pool, store results in your customer's bucket, and invoice each billable unit (credit or rendered image) with margin on top of Photta's credit cost.
- 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
Fan out over your customers' catalogs, dispatch try-on jobs per product, invoice by the credit. The same primitives that Photta exposes to individual developers compose into a white-label SaaS — if you respect the boundaries.
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')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.statusimport os, requests
res = requests.post(
"https://api.photta.app/api/v1/tryon/apparel",
headers={"Authorization": f"Bearer {os.environ['PHOTTA_API_KEY']}"},
json={
"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."
},
)
data = res.json()["data"] # data["id"], data["status"]How it works
From one key to a multi-tenant service
Five architecture decisions you need to make before writing production code.
Step 1
Define your product contract
Decide what your customer gets per billing unit: one rendered image? A batch? A monthly credit pool? Your answer drives everything else — queue depth, retry policy, pricing page copy.
Step 2
Provision Photta keys per tenant
Small scale: one pooled key, track usage per tenant in your database. Larger scale: one Photta key per tenant, managed through the Photta dashboard — clearer attribution, smaller blast radius on a leak.
Step 3
Fan out through a queue
For each product in the customer feed, enqueue a photo job. Never submit synchronously during a CSV import — you will hit the 600-requests-per-minute rate limit and lose jobs to 429s.
Step 4
Margin on top of the credit price
Each 4K apparel render costs you 6 credits. Every invoice you send should be credits × your margin. Record the raw credit cost in your ledger so finance can reconcile Photta's invoice against your revenue line.
Step 5
Monitor latency and failure rate
Track the completion time + failure rate per tenant. When a customer's photos consistently take longer than 4 minutes or fail repeatedly, it's almost always a bad input (corrupt URL, unsupported product_type) — not a Photta issue.
Three patterns you'll need
Fanout, per-tenant dispatch, billing ledger — the load-bearing pieces of a photography SaaS.
// For each product in the customer's feed, kick off a try-on.
for (const product of catalog) {
await photoQueue.add("photo", {
customerId: product.customer_id,
productUrl: product.image,
productType: product.type, // "top" | "bottom" | "top_and_bottom" | "one_piece"
});
}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// A completed apparel job costs 5 credits at 2K and 6 at 4K.
// Record it to your billing pipeline so you can margin on top of it.
await billingLedger.append({
customer: data.customerId,
sku: "photo-4k",
quantity: 1,
wholesaleCost: 6, // credits, = your Photta spend
});Questions developers ask
Running a service on top of Photta
Do I need a separate Photta API key per tenant?
No, but it helps at scale. Below a handful of customers, one pooled key with per-tenant usage tracking in your own database is fine. Above that, a key per tenant gives you cleaner attribution, easier rotation, and a smaller blast radius when something leaks.
What do I do when credits run out?
The API returns 402 insufficient_credits with required and available counts. Set a low-water mark (e.g. 100 credits) and top up automatically before jobs start failing. Failed jobs refund their credits, so a burst of 402s doesn't compound the damage.
How should I price my service?
Photta charges 5 credits at 2K, 6 credits at 4K. Convert that into your retail currency (cost × your margin × credit conversion) and decide whether to bill per image, per batch or per month. Most photography SaaS products end up billing per-image with a monthly minimum.
What SLAs does Photta offer?
Photta's documented completion window is 1.5 to 4 minutes per job. There is no hard uptime SLA published. If your SaaS commits to a turnaround of its own, build the slack into your own contract (e.g. 'photos delivered within 1 hour' gives you 10x headroom) and track per-tenant latency to catch regressions early.
Can I white-label the output?
Yes. The returned images don't carry Photta branding. You can deliver them to your customer's bucket with your own CDN domain in front — your customer never needs to know that Photta's pipeline produced them. The API itself is not white-label — the key + dashboard are Photta-branded.
Related pages
Reference
Capabilities
Virtual try-on API for apparel
REST API that places apparel on AI mannequins. Asynchronous, 1.5–4 minute generation, 5 credits at 2K, 6 at 4K. cURL, Node.js and Python examples.
ReadQuickstart
First Photta image in under five minutes.
Sign up, generate an API key, run your first cURL call, poll until it completes, persist the result. Five steps, documented end-to-end.
ReadCapabilities
Ghost mannequin API for hollow-man product photos
AI ghost mannequin endpoint. Remove the mannequin from a garment photo and preserve interior detail. 3D or flat-lay, batch processing, 4 credits at 2K.
Read
Every figure on this page comes from the Photta API docs · checked
Ship a photography SaaS on top of Photta
Same API, your brand, your margin. Grab an API key, wire the three patterns above into your workers, and you're halfway to launch.