API-Dokumentation

PhotoFig API

Stellen Sie Bildbearbeitungen und Größenanpassungen in die Warteschlange, wenden Sie Vorlagen auf ganze Stapel an, verfolgen Sie den Status und empfangen Sie signierte Webhook-Ereignisse per API-Schlüssel.

Benötigen Sie ein maschinenlesbares Schema? OpenAPI-JSON herunterladen.

Auf dieser Seite

Schnellstart

Erstellen Sie einen API-Schlüssel unter Einstellungen. Ersetzen Sie unten YOUR_API_KEY und speichern Sie ein Foto als product.jpg.

  1. Foto absenden

    Laden Sie das Foto hoch, um einen Produktschatten hinzuzufügen. Die Antwort enthält eine Job-ID und eine statusUrl.

    curl https://api.photofig.com/v1/tools/ai-shadows/edit \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -F "image=@product.jpg"
  2. Jobstatus prüfen

    Ersetzen Sie STATUS_URL durch die zurückgegebene statusUrl. Lautet der Status queued oder processing, warten Sie kurz vor der nächsten Abfrage.

    curl "STATUS_URL" \
      -H "Authorization: Bearer YOUR_API_KEY"
  3. Ergebnis herunterladen

    Sobald der Status completed lautet, ersetzen Sie RESULT_URL durch die zurückgegebene resultUrl, um das Bild zu speichern.

    curl -fL "RESULT_URL" -o photofig-result.png

Nutzen Sie Webhooks, um Abschluss-Events automatisch zu empfangen.

Authentifizierung

API-Routen akzeptieren API-Schlüssel aus den Einstellungen. Der vollständige geheime Schlüssel wird nur einmalig beim Erstellen angezeigt.

Authorization: Bearer pf_live_...

API-Schlüssel gelten ausschließlich für die auf dieser Seite dokumentierten Endpunkte; alle anderen PhotoFig-Routen lehnen sie ab. Ein Schlüssel handelt im Namen der Person, die ihn erstellt hat, und in dem Arbeitsbereich, in dem er angelegt wurde.

Limits und Kontingente

API-Zugriff ist in den Plänen Pro und Studio enthalten. GET /v1/account zeigt die Limits Ihres Tarifs, darunter das stündliche Anfragekontingent unter limits.rateLimitPerHour.

Jede authentifizierte Anfrage zählt zum stündlichen Kontingent, einschließlich Statusabfragen. Antworten enthalten die Header X-RateLimit-Limit und X-RateLimit-Remaining. Ist das Kontingent erschöpft, antwortet die API mit 429 rate_limit_exceeded sowie einem Retry-After-Header.

mask verbraucht Hintergrundentfernungen, ai-bg und ai-shadows verbrauchen jeweils einen KI-Credit, und resize verbraucht keines von beidem. Credits werden erst beim erfolgreichen Abschluss eines Jobs abgezogen.

Wartende und laufende Jobs zählen zum Limit für parallele Jobs Ihres Plans. Wird es überschritten, lehnt die API neue Bearbeitungen mit 429 too_many_jobs ab, bis laufende Jobs abgeschlossen sind.

POST /v1/uploads und POST /v1/tools/{tool_id}/edit unterstützen den optionalen Header X-Idempotency-Key. Wiederholte Anfragen mit demselben Schlüssel liefern die ursprüngliche Antwort zurück, ohne einen zweiten Job zu starten. Verwenden Sie daher für jeden neuen Vorgang einen eigenen Schlüssel.

Konto

GET/v1/account

Nutzen Sie diesen Endpunkt als schnellen Verbindungstest sowie zum Abrufen von Planlimits, verbleibenden Credits und verfügbaren Tools.

{
  "accountId": "uuid",
  "workspaceId": "uuid",
  "plan": "pro",
  "apiEnabled": true,
  "credits": {
    "remaining": 2000,
    "bonusRemaining": 0,
    "periodEndsAt": "2026-11-01T00:00:00Z"
  },
  "limits": {
    "maxFileSizeBytes": 10485760,
    "rateLimitPerHour": 60,
    "concurrentJobs": 3,
    "maxApiKeys": 1,
    "freeBgRemovals": 0,
    "bgRemovalsUsed": 0,
    "aiCredits": 2000
  },
  "tools": [
    "mask",
    "ai-bg",
    "ai-shadows",
    "resize"
  ]
}

Tools

GET/v1/tools
GET/v1/tools/{tool_id}

Jedes Tool akzeptiert ein normales Produktbild per imageUrl, uploadSessionId oder Multipart-Upload. Sie müssen mask nicht vorab aufrufen: ai-bg und ai-shadows stellen das Produkt automatisch selbst frei.

mask

Entfernt den Hintergrund und liefert einen freigestellten PNG-Ausschnitt mit Transparenz. Ideal, wenn Sie das isolierte Produkt für eigenes Compositing oder Marktplatz-Workflows benötigen.

ai-shadows

Fügt einen realistischen Produktschatten hinzu und liefert ein Bild, das sich direkt auf einem ruhigen Hintergrund platzieren lässt. Funktioniert am besten bei Produktfotos, auf denen das Motiv klar erkennbar und nicht durch eine unruhige Umgebung verdeckt ist.

ai-bg

Generiert einen neuen Produkthintergrund anhand einer kurzen Szenenbeschreibung wie warm oak tabletop oder minimal white studio. Übergeben Sie das Produktbild direkt; ein separater Aufruf zur Hintergrundentfernung ist nicht nötig.

resize

Passt ein Foto samt eigenem Hintergrund exakt an eine Zielgröße an, genau wie „Fotogröße ändern“ in der App. Wählen Sie fit oder fill, die Ausrichtung und die Hintergrundfüllung. Verbraucht keine KI-Credits.

Hochladen und Bearbeiten in einem Aufruf

POST/v1/tools/{tool_id}/edit

Der einfachste Weg: Übergeben Sie eine imageUrl, wenn das Quellbild bereits per URL erreichbar ist, oder senden Sie eine lokale Datei als Multipart-Feld image. Ideal, wenn Sie genau ein Tool auf ein einzelnes Bild anwenden möchten.

Wählen Sie diese Variante, wenn Sie ein einzelnes Bild einmalig bearbeiten und die hochgeladene Quelldatei nicht erneut verwenden müssen.

curl -X POST https://api.photofig.com/v1/tools/ai-shadows/edit \
  -H "Authorization: Bearer pf_live_..." \
  -F "image=@product.jpg" \
  -F "seed=128742"

Zuerst hochladen, später bearbeiten

POST/v1/uploads

Erstellen Sie eine Upload-Session, um die Bilddaten direkt in den Speicher hochzuladen, und starten Sie anschließend eine Bearbeitung mit der zurückgegebenen uploadSessionId. Es gilt dasselbe Größenlimit wie bei Multipart-Anfragen; jede Session gilt für genau eine Bearbeitung.

Wählen Sie diesen Weg, wenn Ihr Client die Bilddatei nicht direkt im Bearbeitungsaufruf übertragen soll, etwa beim direkten Upload aus dem Browser.

UPLOAD_JSON=$(curl -s -X POST https://api.photofig.com/v1/uploads \
  -H "Authorization: Bearer pf_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "contentType": "image/jpeg",
    "filename": "product.jpg",
    "sizeBytes": 1842031
  }')

curl -X PUT "$(echo "$UPLOAD_JSON" | jq -r '.uploadUrl')" \
  -H "Content-Type: image/jpeg" \
  --data-binary @product.jpg

curl -X POST https://api.photofig.com/v1/tools/ai-shadows/edit \
  -H "Authorization: Bearer pf_live_..." \
  -H "Content-Type: application/json" \
  -d "{
    \"uploadSessionId\": \"$(echo "$UPLOAD_JSON" | jq -r '.uploadSessionId')\",
    \"parameters\": { \"seed\": 128742 }
  }"

Bearbeitungen starten

POST/v1/tools/{tool_id}/edit

Starten Sie Bearbeitungen mit imageUrl, uploadSessionId oder dem Multipart-Feld image. Die Antwort liefert eine Job-ID für Statusabfragen, Abbruch, Löschung und die Zuordnung von Webhook-Events. Parameter, die ein Tool nicht unterstützt, werden ignoriert.

KI-Hintergrund

Der Endpunkt für KI-Hintergründe liefert die besten Ergebnisse mit einer kurzen, prägnanten Szenenbeschreibung: Umgebung, Untergrund, Lichtstimmung oder Atmosphäre in wenigen Worten. Gute Beispiele sind warm oak tabletop,minimal white studio, and soft morning kitchen light.

curl -X POST https://api.photofig.com/v1/tools/ai-bg/edit \
  -H "Authorization: Bearer pf_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "imageUrl": "https://cdn.example.com/product.png",
    "parameters": {
      "theme": "warm oak tabletop",
      "seed": 128742
    }
  }'

Product Shadow

curl -X POST https://api.photofig.com/v1/tools/ai-shadows/edit \
  -H "Authorization: Bearer pf_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "imageUrl": "https://cdn.example.com/product.png",
    "parameters": { "seed": 128742 }
  }'

Mask

mask benötigt keine Parameter und gibt einen freigestellten PNG-Ausschnitt mit Transparenz zurück.

curl -X POST https://api.photofig.com/v1/tools/mask/edit \
  -H "Authorization: Bearer pf_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "imageUrl": "https://cdn.example.com/product.png"
  }'

Resize

width und height legen die Ausgabegröße in Pixeln fest (100 bis 4096). mode akzeptiert fit (gesamtes Foto bleibt sichtbar, Standard), fill (füllt die Fläche und schneidet Überstände ab), width oder height. horizontal und vertical richten das Foto aus, und background füllt freie Flächen: transparent, ein #RRGGBB-Farbwert oder ein Verlaufsobjekt. Das Ergebnis ist immer ein PNG.

curl -X POST https://api.photofig.com/v1/tools/resize/edit \
  -H "Authorization: Bearer pf_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "imageUrl": "https://cdn.example.com/product.jpg",
    "parameters": {
      "width": 1000,
      "height": 1000,
      "mode": "fit",
      "background": "#ffffff"
    }
  }'

Jobs

GET/v1/jobs
GET/v1/jobs/{job_id}
POST/v1/jobs/{job_id}/cancel
DELETE/v1/jobs/{job_id}

API-Jobs auflisten, abfragen, abbrechen oder löschen. API-Jobs erscheinen nicht in der App unter Uploads oder Designs, beim Löschen werden jedoch alle zugehörigen API-Artefakte entfernt.

GET /v1/jobs/{job_id} gibt den aktuellen Jobstatus zurück. Sobald er completed lautet, laden Sie das Ergebnis vor expiresAt über resultUrl herunter. Jede Statusabfrage zählt zu Ihrem stündlichen Anfragekontingent; nutzen Sie Webhooks für automatische Abschluss-Events.

{
  "id": "api_edit_uuid",
  "tool": "ai-shadows",
  "status": "completed",
  "createdAt": "2026-07-15T10:15:00Z",
  "startedAt": "2026-07-15T10:15:04Z",
  "finishedAt": "2026-07-15T10:15:23Z",
  "statusUrl": "https://api.photofig.com/v1/jobs/api_edit_uuid",
  "resultUrl": "https://storage.example.com/signed-result-url",
  "thumbnailUrl": "https://storage.example.com/signed-thumbnail-url",
  "expiresAt": "2026-07-15T11:15:23Z",
  "error": null
}

Vorlagen

GET/v1/templates
POST/v1/templates
GET/v1/templates/{template_id}
PATCH/v1/templates/{template_id}
DELETE/v1/templates/{template_id}

Eine Vorlage bündelt einen kompletten Look für viele Fotos: Hintergrundentfernung, Platzierung, Hintergrund und Schatten, Randabstand sowie die gewünschten Exportgrößen. Über die API erstellte Vorlagen lassen sich in der PhotoFig-App öffnen und bearbeiten, und umgekehrt. Systemvorlagen sind sofort einsatzbereit und schreibgeschützt.

mask und resize sind Pflichtfelder; alle weiteren Schritte sind optional und werden in fester Reihenfolge ausgeführt. Unbekannte Schritte oder Felder werden abgewiesen, und alle Werte müssen innerhalb der im Editor unterstützten Bereiche liegen. Das OpenAPI-Schema beschreibt sämtliche Felder.

curl -X POST https://api.photofig.com/v1/templates \
  -H "Authorization: Bearer pf_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Cream catalog",
    "steps": {
      "mask": {},
      "reposition": { "horizontal": "center", "vertical": "center", "scale": 0.85 },
      "background": { "backgroundType": "solid", "color": "#f6f1ea" },
      "ai-shadows": { "opacity": 0.8 },
      "resize": { "mode": "fit", "targets": [{ "width": 2000, "height": 2000 }] }
    },
    "export": { "format": "jpg", "background": "#ffffff" }
  }'

creditsPerPhoto gibt an, was die Vorlage pro Foto verbraucht, beispielsweise einen KI-Credit für ai-shadows.

Stapel

POST/v1/batches
POST/v1/batches/{batch_id}/uploads
POST/v1/batches/{batch_id}/uploads/{upload_id}/complete
POST/v1/batches/{batch_id}/process
GET/v1/batches/{batch_id}
GET/v1/batches
POST/v1/batches/{batch_id}/cancel
DELETE/v1/batches/{batch_id}

Ein Stapel wendet eine Vorlage auf viele Fotos an. Legen Sie den Stapel an, fügen Sie die Fotos hinzu und starten Sie anschließend die Verarbeitung mit einer Vorlage. Die Fotos behalten dabei ihre übergebene Reihenfolge.

Jedes Foto wird direkt in den Speicher geladen: Fordern Sie einen Upload an, senden Sie die Bytes per PUT an uploadUrl und schließen Sie den Upload ab.

BATCH_ID=$(curl -s -X POST https://api.photofig.com/v1/batches \
  -H "Authorization: Bearer pf_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "name": "Spring arrivals" }' | jq -r '.id')

# For each photo: ask for an upload, PUT the bytes, complete it.
UPLOAD=$(curl -s -X POST "https://api.photofig.com/v1/batches/$BATCH_ID/uploads" \
  -H "Authorization: Bearer pf_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "filename": "boots.jpg", "contentType": "image/jpeg", "sizeBytes": 1842031, "position": 0 }')
curl -X PUT "$(echo "$UPLOAD" | jq -r '.uploadUrl')" \
  -H "Content-Type: image/jpeg" --data-binary @boots.jpg
curl -X POST "https://api.photofig.com/v1/batches/$BATCH_ID/uploads/$(echo "$UPLOAD" | jq -r '.uploadId')/complete" \
  -H "Authorization: Bearer pf_live_..."

curl -X POST "https://api.photofig.com/v1/batches/$BATCH_ID/process" \
  -H "Authorization: Bearer pf_live_..." \
  -H "Content-Type: application/json" \
  -d '{ "templateId": "TEMPLATE_ID" }'

Automatisch erfahren, wann ein Stapel fertig ist

Registrieren Sie einmalig einen Webhook für batch.completed, statt laufend den Status abzufragen. PhotoFig ruft Ihren Endpunkt auf, sobald ein Stapel abgeschlossen ist, inklusive Stapel-ID sowie der Anzahl erfolgreicher und fehlgeschlagener Fotos.

curl -X POST https://api.photofig.com/v1/webhooks \
  -H "Authorization: Bearer pf_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/photofig/webhooks",
    "events": ["batch.completed"]
  }'
{
  "event": "batch.completed",
  "eventId": "uuid",
  "createdAt": "2026-10-06T12:00:00Z",
  "data": {
    "batchId": "uuid",
    "status": "completed",
    "totalItems": 12,
    "completedItems": 12,
    "failedItems": 0
  }
}

Sobald batch.completed eintrifft, rufen Sie den Stapel ab. Jedes fertige Foto enthält einen Vorschaulink mit bis zu 1024 Pixeln Kantenlänge. Hintergrundentfernungen und KI-Credits werden genau wie in der App abgerechnet.

{
  "id": "uuid",
  "name": "Spring arrivals",
  "status": "completed",
  "templateName": "Cream catalog",
  "totalItems": 2,
  "completedItems": 2,
  "failedItems": 0,
  "resultsAvailableUntil": "2026-10-20T12:00:00Z",
  "items": [
    {
      "id": "uuid",
      "position": 0,
      "filename": "boots.jpg",
      "status": "completed",
      "width": 3024,
      "height": 4032,
      "preview": {
        "url": "https://...",
        "width": 1024,
        "height": 1024
      }
    }
  ]
}

Ergebnisse herunterladen

GET/v1/batches/{batch_id}/items/{item_id}/download
GET/v1/batches/{batch_id}/download-url

Laden Sie jedes Ergebnis in voller Auflösung im Exportformat der Vorlage herunter oder beziehen Sie den gesamten Stapel als ZIP-Archiv. Jedes Ergebnis zählt beim ersten Abruf als ein Export, genau wie in der App; erneutes Herunterladen ist kostenlos.

Ergebnisse teilen

POST/v1/batches/{batch_id}/share
GET/v1/batches/{batch_id}/share
DELETE/v1/batches/{batch_id}/share

Ein Freigabelink öffnet eine öffentliche Seite mit Vorher-Nachher-Vorschau und ZIP-Download, ganz ohne Anmeldung. Pro Stapel gibt es genau einen Link: Eine erneute Abfrage gibt denselben Link zurück, und ein Widerruf deaktiviert ihn sofort. Downloads über die Freigabeseite zählen zu Ihren Exporten; die Seite bleibt bis availableUntil gültig. Freigabelinks setzen einen kostenpflichtigen Plan voraus.

curl -X POST "https://api.photofig.com/v1/batches/$BATCH_ID/share" \
  -H "Authorization: Bearer pf_live_..."
{
  "url": "https://photofig.com/share/TOKEN",
  "availableUntil": "2026-10-20T12:00:00Z",
  "createdAt": "2026-10-06T12:05:00Z",
  "downloadCount": 0
}

Webhooks

Über Webhooks informiert PhotoFig Ihren Server automatisch, sobald ein API-Job abgeschlossen ist, fehlschlägt oder abgebrochen wird, sowie wenn ein Stapel fertig verarbeitet ist. Registrieren Sie dazu eine öffentlich erreichbare HTTPS-URL. Ein Endpunkt empfängt Ereignisse für alle Jobs und Stapel, die mit den API-Schlüsseln seines Inhabers gestartet wurden.

GET/v1/webhooks
POST/v1/webhooks
GET/v1/webhooks/{webhook_id}
PATCH/v1/webhooks/{webhook_id}
DELETE/v1/webhooks/{webhook_id}
POST/v1/webhooks/{webhook_id}/test

Unterstützte Events sind webhook.test,job.completed,job.failed,job.cancelled, und batch.completed. Job-Events enthalten die beim Starten der Bearbeitung vergebene Job-ID; batch.completed enthält die Stapel-ID.

{
  "event": "job.completed",
  "eventId": "uuid",
  "createdAt": "2026-07-15T10:15:23Z",
  "data": {
    "id": "api_edit_uuid",
    "tool": "ai-shadows",
    "status": "completed",
    "resultUrl": "https://storage.example.com/signed-result-url",
    "thumbnailUrl": "https://storage.example.com/signed-thumbnail-url",
    "expiresAt": "2026-07-15T11:15:23Z"
  }
}

Jede Zustellung verifizieren

Jede Anfrage enthält die Header PhotoFig-Webhook-Timestamp und PhotoFig-Webhook-Signature. Berechnen Sie mit dem Secret des Endpunkts den HMAC-SHA256 über den Zeitstempel, einen Punkt und den unveränderten Request-Body und vergleichen Sie das Ergebnis mit dem Wert hinter v1=. Lehnen Sie Zeitstempel ab, die älter als wenige Minuten sind. Das Secret wird nur einmalig beim Anlegen des Endpunkts angezeigt.

import crypto from 'node:crypto';

// rawBody is the request body exactly as received, before JSON parsing.
export function verifyPhotoFigWebhook(headers, rawBody, secret) {
  const timestamp = headers['photofig-webhook-timestamp'];
  const signature = headers['photofig-webhook-signature'] ?? '';
  if (Math.abs(Date.now() / 1000 - Number(timestamp)) > 300) return false;

  const expected = 'v1=' + crypto
    .createHmac('sha256', secret)
    .update(`${timestamp}.${rawBody}`)
    .digest('hex');
  return signature.length === expected.length
    && crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}

Antworten Sie innerhalb von 10 Sekunden mit einem 2xx-Statuscode. Andere Antworten werden nach 1 Minute, 5 Minuten, 30 Minuten, 2 Stunden und 12 Stunden erneut zugestellt. PhotoFig-Webhook-Id bleibt über alle Zustellversuche hinweg identisch, sodass Sie Duplikate zuverlässig filtern können. Download-Links im Payload werden für jeden Zustellversuch frisch signiert und verlieren ihre Gültigkeit, sobald das Ergebnis abläuft.

Fehler

Fehlerantworten enthalten einen stabilen maschinenlesbaren code sowie eine verständliche Beschreibung in message. Nutzen Sie in Ihrer Client-Logik stets das Feld code zur Fehlerbehandlung.

{
  "code": "invalid_request",
  "message": "imageUrl or uploadSessionId is required"
}

Häufige Fehlercodes

invalid_request
Ein Pflichtparameter fehlt oder ist ungültig; Details stehen in der Fehlermeldung.
api_key_not_allowed
Ein API-Schlüssel wurde für eine Route außerhalb der öffentlichen API verwendet.
api_access_disabled
Der Tarif des Arbeitsbereichs umfasst keinen API-Zugriff.
insufficient_funds
Für dieses Tool sind keine KI-Credits oder Hintergrundentfernungen mehr verfügbar.
rate_limit_exceeded
Das stündliche Anfragekontingent ist ausgeschöpft; warten Sie die in Retry-After angegebene Zeit ab.
too_many_jobs
Zu viele Jobs warten oder laufen gleichzeitig; versuchen Sie es erneut, sobald laufende Jobs abgeschlossen sind.
tool_unavailable
Die Worker für dieses Tool sind kurzzeitig nicht erreichbar; versuchen Sie es in Kürze erneut.
webhook_limit_reached
Für diesen Arbeitsbereich wurde die maximale Anzahl an Webhook-Endpunkten erreicht.

Aufbewahrung der Ergebnisse

Abgeschlossene API-Jobs bleiben über GET /v1/jobs und GET /v1/jobs/{job_id} abrufbar. Die Statusantwort enthält signierte Links unter resultUrl und thumbnailUrl, solange die Ausgabedateien vorgehalten werden.

API-Artefakte werden getrennt von den interaktiven Uploads und Designs der Web-App gespeichert und erscheinen nicht in der App-Bibliothek.

API-Jobeinträge sowie die zugehörigen Eingabe-, Ergebnis- und Vorschaudateien werden nach dem Status completed, failed oder cancelled für 1 Stunde aufbewahrt. Das Feld expiresAt gibt den geplanten Löschzeitpunkt an.

Rufen Sie DELETE /v1/jobs/{job_id} auf, sobald Sie nicht mehr benötigte Ergebnisse heruntergeladen haben. Dadurch werden noch laufende Jobs nach Möglichkeit abgebrochen und der Jobeintrag samt Dateien vor Ablauf der automatischen Aufbewahrungsfrist gelöscht.