Python · Ghost mannequin API
Ghost mannequin API in Python
In één zin
Installeer requests, laad PHOTTA_API_KEY vanuit env, schrijf een photta()-wrapper die de Bearer-sleutel verstuurt en een getypeerde PhottaError opwerpt bij niet-2xx-antwoorden, voer vervolgens een POST uit naar /api/v1/ghost-mannequin en voer elke 3 seconden polling uit op /api/v1/ghost-mannequin/{id} totdat de status completed is.
- Typische duur: 1.5–4 min
- Credits: 4 credits bij 2K · 5 credits bij 4K
- Verwerking: async, polling
- Limieten: 600 requests/min
- Authenticatie: Bearer key
Elk getal op deze pagina is afkomstig uit de Photta-API-documentatie · gecontroleerd
RESPONSE=$(curl -s -X POST https://api.photta.app/api/v1/ghost-mannequin \
-H "Authorization: Bearer $PHOTTA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"product_image": "https://cdn.yourstore.com/products/jacket-front.jpg",
"back_image": "https://cdn.yourstore.com/products/jacket-back.jpg",
"image_side": "front",
"angle": "side",
"style": "3d",
"background_color": "white",
"resolution": "2K",
"aspect_ratio": "3:4",
"user_instruction": "closed front, cream interior lining",
"brand_label_id": "7cc9f988-068b-44cd-8004-22f486b10e67"
}')
ID=$(echo "$RESPONSE" | jq -r '.data.id')
# $ID is data.id from the POST response. Poll every 3 seconds until status is "completed" or "failed".
for i in $(seq 1 120); do
RESULT=$(curl -s "https://api.photta.app/api/v1/ghost-mannequin/$ID" -H "Authorization: Bearer $PHOTTA_API_KEY")
STATUS=$(echo "$RESULT" | jq -r '.data.status')
[ "$STATUS" = "completed" ] && break
[ "$STATUS" = "failed" ] && echo "generation failed" && exit 1
sleep 3
done
echo "$RESULT" | jq -r '.data.output_url'const res = await fetch("https://api.photta.app/api/v1/ghost-mannequin", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.PHOTTA_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
"product_image": "https://cdn.yourstore.com/products/jacket-front.jpg",
"back_image": "https://cdn.yourstore.com/products/jacket-back.jpg",
"image_side": "front",
"angle": "side",
"style": "3d",
"background_color": "white",
"resolution": "2K",
"aspect_ratio": "3:4",
"user_instruction": "closed front, cream interior lining",
"brand_label_id": "7cc9f988-068b-44cd-8004-22f486b10e67"
}),
});
const { data } = await res.json(); // data.id, data.status
async function waitFor(id) {
for (let attempt = 0; attempt < 120; attempt++) {
const res = await fetch(`https://api.photta.app/api/v1/ghost-mannequin/${id}`, { headers: { Authorization: `Bearer ${process.env.PHOTTA_API_KEY}` } });
const { data } = await res.json();
if (data.status === "completed") return data.output_url;
if (data.status === "failed") throw new Error(data.error_message ?? "generation failed");
await new Promise((r) => setTimeout(r, 3000));
}
throw new Error("timed out after 6 minutes");
}import os, requests
res = requests.post(
"https://api.photta.app/api/v1/ghost-mannequin",
headers={"Authorization": f"Bearer {os.environ['PHOTTA_API_KEY']}"},
json={
"product_image": "https://cdn.yourstore.com/products/jacket-front.jpg",
"back_image": "https://cdn.yourstore.com/products/jacket-back.jpg",
"image_side": "front",
"angle": "side",
"style": "3d",
"background_color": "white",
"resolution": "2K",
"aspect_ratio": "3:4",
"user_instruction": "closed front, cream interior lining",
"brand_label_id": "7cc9f988-068b-44cd-8004-22f486b10e67"
},
)
data = res.json()["data"] # data["id"], data["status"]
import time
def wait_for(job_id):
for _ in range(120):
res = requests.get(f"https://api.photta.app/api/v1/ghost-mannequin/{job_id}", headers={"Authorization": f"Bearer {os.environ['PHOTTA_API_KEY']}"})
data = res.json()["data"]
if data["status"] == "completed":
return data["output_url"]
if data["status"] == "failed":
raise RuntimeError(data.get("error_message", "generation failed"))
time.sleep(3)
raise TimeoutError("timed out after 6 minutes")In één oogopslag
In één oogopslag
- Endpoint
- POST /api/v1/ghost-mannequin
- Authenticatie
- Bearer API key
- Verwerking
- Asynchroon — poll het status-endpoint
- Typische duur
- 1.5–4 min
- Credits
- 4 credits bij 2K · 5 credits bij 4K
- Beeldverhoudingen
- 3:4 · 1:1 · 4:3 · 9:16 · 16:9
- Invoerlimieten
- Tot 10 MB per afbeelding; JPEG, PNG, WebP
- Idempotent
- Nee
Hoe het werkt
Vijf stappen, nul Photta-specifieke afhankelijkheden — requests dekt alles af.
Stap 1
Meld je aan en genereer een sleutel
Hetzelfde pad als bij elke andere taal: ai.photta.app → Developers → Generate API key. Sleutels beginnen met `photta_live_` en werken voor elke Photta-functionaliteit.
Stap 2
Laad de sleutel vanuit env
Stel `PHOTTA_API_KEY` in binnen de omgeving en lees deze uit via `os.environ`. Laad deze in FastAPI of Django eenmalig bij het opstarten in een settings-module. Neem de sleutel niet op in de broncode of in de openbare Git-geschiedenis.
python3 -m pip install requests export PHOTTA_API_KEY="photta_live_xxxxx"Stap 3
Schrijf een requests-wrapper
Een `photta_request()`-functie van dertig regels verzorgt de basis-URL, de Authorization-header, JSON-serialisatie en foutafhandeling. Dat is de enige abstractie die je nodig hebt totdat de Python SDK verschijnt.
# photta.py — one helper for every endpoint import os, requests BASE = "https://api.photta.app/api/v1" class PhottaError(Exception): def __init__(self, status, error, retry_after=None): super().__init__(error.get("message", "request failed")) self.status, self.type, self.retry_after = status, error.get("type"), retry_after def photta(method, path, **kwargs): res = requests.request(method, BASE + path, headers={"Authorization": f"Bearer {os.environ['PHOTTA_API_KEY']}"}, timeout=30, **kwargs) body = res.json() if not res.ok: raise PhottaError(res.status_code, body.get("error", {}), res.headers.get("Retry-After")) return bodyStap 4
Verzenden en pollen
POST naar `/api/v1/ghost-mannequin` om een generatie-ID op te halen en poll vervolgens `/api/v1/ghost-mannequin/{id}` met een interval van 3 seconden. Splits in Celery of RQ de poll-lus op over meerdere taken, zodat een taak van meerdere minuten geen worker bezet houdt.
import os, requests res = requests.post( "https://api.photta.app/api/v1/ghost-mannequin", headers={"Authorization": f"Bearer {os.environ['PHOTTA_API_KEY']}"}, json={ "product_image": "https://cdn.yourstore.com/products/jacket-front.jpg", "back_image": "https://cdn.yourstore.com/products/jacket-back.jpg", "image_side": "front", "angle": "side", "style": "3d", "background_color": "white", "resolution": "2K", "aspect_ratio": "3:4", "user_instruction": "closed front, cream interior lining", "brand_label_id": "7cc9f988-068b-44cd-8004-22f486b10e67" }, ) data = res.json()["data"] # data["id"], data["status"] import time def wait_for(job_id): for _ in range(120): res = requests.get(f"https://api.photta.app/api/v1/ghost-mannequin/{job_id}", headers={"Authorization": f"Bearer {os.environ['PHOTTA_API_KEY']}"}) data = res.json()["data"] if data["status"] == "completed": return data["output_url"] if data["status"] == "failed": raise RuntimeError(data.get("error_message", "generation failed")) time.sleep(3) raise TimeoutError("timed out after 6 minutes")Stap 5
Sla het resultaat op
De voltooide payload bevat `output_url` en `thumbnail_url`. Download de bytes naar je eigen objectopslag — S3, GCS, Cloudflare R2 — zodat je product voor weergave op lange termijn niet afhankelijk is van het CDN van Photta.
Errors
- 400
invalid_request_error - The request is malformed or contains invalid parameters.
- 401
authentication_error - The API key is missing, invalid, or expired.
- 402
insufficient_credits_error - Your account does not have enough credits.
- 404
not_found_error - The requested resource does not exist.
- 409
conflict_error - The request conflicts with current state — e.g. your concurrent-batch cap is reached.
- 429
rate_limit_error - Too many requests. Slow down and retry.Retry-After: 30
- 500
api_error - An internal server error occurred. Retry later.
try:
photta("POST", "/ghost-mannequin", json={
"product_image": "https://cdn.yourstore.com/products/jacket-front.jpg",
"back_image": "https://cdn.yourstore.com/products/jacket-back.jpg",
"image_side": "front",
"angle": "side",
"style": "3d",
"background_color": "white",
"resolution": "2K",
"aspect_ratio": "3:4",
"user_instruction": "closed front, cream interior lining",
"brand_label_id": "7cc9f988-068b-44cd-8004-22f486b10e67"
})
except PhottaError as e:
if e.status == 402:
print("insufficient_credits_error: top up before retrying")
elif e.status == 429:
time.sleep(int(e.retry_after or 30))
else:
raiseLimieten
- 600 verzoeken per minuut per API key (Vast venster; de limiet is identiek op elk abonnement)
- Een 429 bevat Retry-After: 30 seconden
- Tot 10 MB per afbeelding
- Formaten: JPEG, PNG, WebP
- Gelijktijdige batches per abonnement: Free 1 · Hobby 2 · Seller 3 · Brand 4 · Studio 6
- Uitsluitend polling — de API stuurt geen webhooks.
Waarom requests vandaag de juiste keuze is
- Geen Photta-specifieke afhankelijkheid — requests zit al in de meeste Python-projecten
- Werkt overal waar Python draait: Django, FastAPI, Flask, Celery-workers, Lambda, scripts
- De client-wrapper telt ongeveer dertig regels — plak hem in photta.py en ga door
- Combineert via httpx met asyncio wanneer je parallelle verzoeken moet indienen
Wat het niet doet
- Nog geen officieel Photta Python-package — REST met requests is het gedocumenteerde patroon
- Polling is het enige signaal voor voltooiing; de API verstuurt geen webhooks
- Uitsluitend Bearer-sleutel; er is geen OAuth client-credentials-flow
Veelgestelde vragen van developers
Is er een officiële Photta Python SDK?
Nog niet. Het ondersteunde integratiepad is de requests-library (synchroon) of httpx (asynchroon) — voor beide volstaat een minimale wrapper, en de wrapper op deze pagina werkt voor elke capability.
Welke Python-versies worden ondersteund?
Python 3.9 en hoger. De wrapper gebruikt type hints, f-strings en `str | None`-syntaxis, wat prima werkt op 3.10+. Vervang op 3.9 `str | None` door `Optional[str]`. requests zelf ondersteunt officieel 3.8+, maar 3.9+ is het praktische minimum voor moderne Photta-projecten.
Moet ik requests of httpx gebruiken?
requests als je een handvol sequentiële aanroepen doet — het is eenvoudiger en zit al in de meeste codebases. httpx als je asynchrone gelijktijdigheid nodig hebt (parallel verzenden, bulk-backfills) of HTTP/2. De wrapper is in beide gevallen minuscuul; vervang `requests.request` door `httpx.Client().request` en de rest van de code blijft identiek.
Kan ik dit aanroepen vanuit Django?
Ja. Plaats de wrapper in `services/photta.py` en importeer deze vanuit een view of een Celery-taak. Roep de API niet aan binnen een synchrone request-handler als de taak lang duurt — dien de aanvraag in vanuit de view, retourneer het generatie-ID en poll vanuit een achtergrondtaak of een Channels-consumer.
Hoe poll ik vanuit een Celery-worker?
Dien de taak in vanuit één worker-taak en plan vervolgens een vervolgtaak in (via `apply_async(countdown=3)`) die één keer pollt en zichzelf opnieuw inplant totdat de taak voltooid is of de drempelwaarde voor maximale pogingen wordt bereikt. Dit houdt workers vrij en voorkomt langdurige taken die autoscalers verstoren.
Hoe geeft de API fouten aan?
Niet-2xx-antwoorden bevatten een JSON-body met een `error`-object: `type`, `code`, `message`, plus `param` bij 400's en `retry_after` bij 429's. De wrapper op deze pagina genereert een `PhottaError` die al deze gegevens bevat, zodat je aanroepende code kan vertakken op basis van de statuscode zonder zelf de body te hoeven parsen.
Gerelateerde pagina's
Node.js
Ghost mannequin API in Node.js
Roep Photta's ghost mannequin API aan vanuit een Node.js-backend met native fetch. Geen SDK vereist: sla je sleutel op, verzend de taak, poll voor het resultaat.
LezencURL
Ghost mannequin API met cURL
Roep Photta's ghost mannequin API direct aan vanuit de shell met cURL. Verzenden, pollen, downloaden — elk fragment werkt naadloos samen met jq voor gescripte pipelines.
LezenMogelijkheden
Ghost mannequin API voor hollow-man-productfoto's
AI ghost mannequin endpoint. Verwijder de paspop uit een kledingfoto en behoud interne details. 3D of flat-lay, batchverwerking, 4 credits bij 2K.
LezenBouwen
Automatiseer ghost mannequin-extractie voor je catalogus
Recept voor nachtelijke catalogusautomatisering: haal de productupdates van gisteren op, verzend ze in batch naar Photta's ghost-mannequin API, poll de bovenliggende batch, sla ze op in je database.
LezenSnelstartgids
Eerste Photta-afbeelding in minder dan vijf minuten.
Registreer je, genereer een API-sleutel, voer je eerste cURL-call uit, poll totdat deze is voltooid, sla het resultaat op. Vijf stappen, end-to-end gedocumenteerd.
LezenReferentie
Photta API-prijzen
Wat elk Photta API-endpoint kost in credits op 2K en 4K, hoe facturering en restituties werken, en welke endpoints gratis zijn. Geen geldprijs per afbeelding.
Lezen
Elk getal op deze pagina is afkomstig uit de Photta-API-documentatie · gecontroleerd
Probeer de API in vijf minuten
Genereer een Photta API-sleutel, plak het bovenstaande cURL-fragment en je hebt je eerste afbeelding op een model voordat de koffie klaar is.
- 1.5–4 min
- 4 credits bij 2K · 5 credits bij 4K
- async, polling
- 600 requests/min
- Bearer key