Entwickler api.md llms.txt
🌐 Deutsch
API-Key holen

HedaAI Produktbilder-API

12 professionelle E-Commerce-Bilder (8 Hauptbilder + 4 A+ Banner) plus vollständigen Listing-Text aus Produktfotos generieren — programmatisch oder direkt aus dem KI-Agenten per MCP.

$1.00 / Produktnur bei Erfolg berechnet
~10 Minutenasynchron: erstellen → pollen → abrufen
Dauerhafte SpeicherungErgebnisse bleiben im Account, keine URL-Ablauffrist
MCP integriertgehosteter Server für KI-Agenten
Base URL: https://hedaai.com/api/v1  ·  Doku-Mirrors für Agenten: /developers/api.md · /developers/llms.txt

Authentifizierung

API-Key unter hedaai.com/settings/api-keys erstellen (jeder Account funktioniert; neue Accounts erhalten $2.00 Startguthaben ≈ 2 kostenlose Tasks). Der vollständige Key (hda_live_…) und sein Webhook-Secret (whsec_…) werden nur einmal bei der Erstellung angezeigt — sicher aufbewahren. Keys lassen sich benennen, mit einem Ausgabelimit versehen und jederzeit widerrufen.

Authorization: Bearer hda_live_...

Keys werden gehasht gespeichert und sind ausschließlich an den eigenen Account gebunden — ein API-Key kann niemals Daten eines anderen Accounts lesen.

Sandbox-Modus (kostenloses Testen): Solange der Account keine echte Zahlung getätigt hat, tragen generierte Bilder ein Wasserzeichen und es gibt kein 2K-Upscaling — alles andere verhält sich identisch (GET /v1/account meldet "mode": "sandbox_watermarked"). Die erste Zahlung entfernt die Wasserzeichen automatisch von allen zuvor generierten Produkten.

Ausgabelimits: Jeder Key hat ein optionales spend_cap_cents (Standard: unbegrenzt). Ist es erreicht, schlägt die Task-Erstellung mit spend_cap_exceeded (403) fehl.

Antwort-Envelope

{ "status": 200, "code": 200, "message": "", "data": { … } }

Fehler enthalten zusätzlich einen error_code für den programmatischen Abgleich. Transportfehler vs. Task-Fehler: HTTP 4xx/5xx bedeutet, dass die Anfrage fehlgeschlagen ist. Ein Task, der während der Generierung scheitert, ist kein HTTP-Fehler — das Polling liefert 200 mit status: "failed" und einem error-Feld, und es wird nichts berechnet.

Schnellstart

# 1. Task erstellen
curl -X POST https://hedaai.com/api/v1/tasks \
  -H "Authorization: Bearer $HEDAAI_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-12345-attempt-1" \
  -d '{
    "product_name": "stainless steel insulated water bottle",
    "images": ["https://your-cdn.example.com/bottle-front.jpg"],
    "aspect_ratio": "1:1",
    "category": "insulated water bottle 750ml",
    "target_market": "amazon_us"
  }'
# → data.task_id = "3f8a…", data.status = "queued"

# 2. Alle 15–30s pollen bis zum Endstatus
curl -H "Authorization: Bearer $HEDAAI_API_KEY" https://hedaai.com/api/v1/tasks/3f8a…
# → data.status = "succeeded", data.product_id = "9c1b…"

# 3. Fertiges Produkt abrufen (12 Bild-URLs + Listing-Text)
curl -H "Authorization: Bearer $HEDAAI_API_KEY" https://hedaai.com/api/v1/products/9c1b…

POST/v1/tasks

Erstellt einen Generierungs-Task. Optionaler Header: Idempotency-Key (≤64 Zeichen, siehe unten).

FeldTypPflichtHinweise
product_namestringjaKurzer Produktname. Starkes Grounding-Signal — möglichst konkret formulieren.
imagesstring[1–8]jaFoto-URLs (öffentlich http/https, je ≤15MB) und/oder base64 / Data-URIs. Fotos aus mehreren Winkeln verbessern die Detailtreue.
aspect_ratiostringja1:1, 2:3, 3:2, 3:4, 4:3, 9:16, 16:9. Amazon-Hauptbilder verwenden 1:1.
categorystringneinKonkrete Kategorie, z. B. „Ersatzfilter für Staubsauger“. Empfohlen.
brand_namestringneinFließt in Brand-Story-Bilder und Listing-Text ein.
key_featuresstring[≤10]neinVerkaufsargumente, die zwingend sichtbar sein müssen.
specsobjectnein{material, colorway, key_components[], usage_context, use_scenarios[], dimensions[], scale}. Empfohlen — die API hat keinen interaktiven Review-Schritt, das Grounding ergibt sich allein aus den übergebenen Daten.
target_marketstringneinamazon_us (Standard) · shopify · ebay
copy_languagestringneinLocale des Listing-Texts (en-US, de-DE, ja-JP, …). Standard ergibt sich aus dem Zielmarkt.
aplus_formatstringneinbanner (16:9, Standard) · aplus_3_4 · aplus_9_16 · standard_aplus/premium (nur Amazon)
no_human_modelsboolneintrue = keine Personen in irgendeinem Bild.
supplementary_textstring ≤5000neinFreitext-Spezifikationen / Handbuchauszüge, die die KI auswerten kann.
callback_urlstringneinWebhook für den Endstatus (Webhooks).

Gibt ein Task-Objekt zurück:

{
  "task_id": "3f8a…", "status": "queued", "progress": 0,
  "queue_position": 2, "eta_seconds": 840, "cost_cents": 0,
  "created_at": "2026-07-17T08:00:00Z",
  "urls": { "get": "/api/v1/tasks/3f8a…", "cancel": "/api/v1/tasks/3f8a…/cancel" }
}

GET/v1/tasks/{task_id}

Status-Lebenszyklus: queuedprocessingsucceeded | partial_failed | failed | canceled.

Alle 15–30 Sekunden pollen. queue_position / eta_seconds sind befüllt, solange der Task in der Warteschlange steht.

POST/v1/tasks/{task_id}/cancel

Bricht einen Task ab. Kostenlos, solange er in der Warteschlange steht; bereits abgeschlossene Tasks bleiben unberührt (idempotent).

GET/v1/products/{product_id}

{
  "product_id": "9c1b…", "name": "stainless steel insulated water bottle",
  "target_market": "amazon_us", "aspect_ratio": "1:1", "watermarked": false,
  "listing_copy": {
    "title": "…", "bullet_points": ["…","…","…","…","…"], "description": "…",
    "search_terms": "…", "meta_title": "…", "meta_description": "…", "language": "en"
  },
  "images": [
    { "slice_id": "M1", "section": "main", "url": "https://images.hedaai.com/…",
      "url_2k": "https://images.hedaai.com/…", "width": 2048, "height": 2048, "sort_order": 1 }
  ],
  "created_at": "2026-07-17T08:11:32Z"
}

GET/v1/account

{
  "balance_cents": 1250, "paid_balance_cents": 1000, "bonus_balance_cents": 250,
  "has_paid": true, "mode": "live", "price_per_task_cents": 100,
  "key": { "name": "prod-integration", "key_prefix": "hda_live_ab12…cd34",
           "spend_cap_cents": null, "spent_cents": 700 }
}

Idempotenz

Bei POST /v1/tasks einen Idempotency-Key-Header (≤64 Zeichen) mitschicken. Ein Retry mit demselben Key und demselben Body liefert den ursprünglichen Task zurück, statt ein Duplikat zu erstellen (und letztlich zu berechnen). Derselbe Key mit abweichendem Body liefert 409 idempotency_conflict. Für Agenten und Automatisierung dringend empfohlen — Netzwerk-Retries werden damit sicher gegen Doppelbelastung.

Webhooks

callback_url bei der Task-Erstellung setzen, um beim Endstatus ein POST zu erhalten. Events: task.succeeded, task.partial_failed, task.failed, task.canceled.

{ "id": "evt_…", "type": "task.succeeded", "created_at": "2026-07-17T08:11:35Z",
  "data": { /* Task-Objekt — gleiche Struktur wie GET /v1/tasks/{id} */ } }

Signaturen folgen der Spezifikation Standard Webhooks — Header webhook-id, webhook-timestamp, webhook-signature: v1,<base64>. Prüfung mit dem webhook_secret des Keys:

import hmac, hashlib, base64

def verify(secret, msg_id, timestamp, body: bytes, signature_header):
    key = base64.b64decode(secret.removeprefix("whsec_"))
    expected = base64.b64encode(hmac.new(key, f"{msg_id}.{timestamp}.".encode() + body,
                                         hashlib.sha256).digest()).decode()
    return any(hmac.compare_digest(expected, s.split(",", 1)[1])
               for s in signature_header.split() if s.startswith("v1,"))

Zügig mit einem beliebigen 2xx antworten (aufwendige Arbeit asynchron erledigen). Zustellung: ein sofortiger Versuch, Retries nach 3s / 6s / 12s, danach als fehlgeschlagen markiert (Polling funktioniert weiterhin). Veraltete Timestamps (>5 min) ablehnen und per id deduplizieren. callback_url muss ein öffentlicher http(s)-Endpoint sein — private/interne Adressen werden abgelehnt.

Rate-Limits & Nebenläufigkeit

LimitWertBei Überschreitung
Anfragen pro Key120 / min (alle Endpoints)429 rate_limited — Header RateLimit-Limit / -Remaining / -Reset prüfen
Laufende Tasks pro Key2 (queued + processing)429 concurrency_limit — warten, bis ein Task fertig ist
Plattform-API-Kapazitätdynamisch429 api_capacity — in einigen Minuten erneut versuchen

Die Generierung ist rechenintensiv (13–20 KI-Bildaufrufe pro Task), daher wird der Durchsatz über die Slots laufender Tasks geregelt und nicht über die Request-Rate. Mehr Nebenläufigkeit nötig? Kontakt aufnehmen.

Fehler

error_codeHTTPBedeutung
bad_request400Ungültige Parameter — die Meldung benennt das betroffene Feld (z. B. images[2]: image download failed with HTTP 403).
unauthorized401API-Key fehlt, ist ungültig oder wurde widerrufen.
insufficient_credits402Guthaben zu gering; data.balance_cents ist enthalten.
spend_cap_exceeded403Das Ausgabelimit dieses Keys ist ausgeschöpft.
account_disabled / email_not_verified / email_bounced403Sperren auf Account-Ebene.
not_found404Task/Produkt existiert nicht oder gehört zu einem anderen Account.
idempotency_conflict409Gleicher Idempotency-Key, anderer Body.
concurrency_limit / api_capacity / rate_limited429Siehe Limits.
generation_failed / internal_error500Serverseitiger Fehler; ein Retry mit Idempotency-Key ist unbedenklich.

Codebeispiele

Der komplette Ablauf — Task erstellen, bis zum Endstatus pollen, fertiges Produkt abrufen — in der Sprache der Wahl.

API=https://hedaai.com/api/v1

# 1. Task erstellen
TASK_ID=$(curl -sS -X POST "$API/tasks" \
  -H "Authorization: Bearer $HEDAAI_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: sku-8842-v1" \
  -d '{"product_name":"stainless steel insulated water bottle",
       "images":["https://your-cdn.example.com/bottle.jpg"],
       "aspect_ratio":"1:1"}' | jq -r .data.task_id)

# 2. Pollen bis zum Endstatus
while :; do
  TASK=$(curl -sS -H "Authorization: Bearer $HEDAAI_API_KEY" "$API/tasks/$TASK_ID")
  STATUS=$(echo "$TASK" | jq -r .data.status)
  [ "$STATUS" = "queued" ] || [ "$STATUS" = "processing" ] || break
  sleep 20
done

# 3. Bilder + Listing-Text abrufen
if [ "$STATUS" = "succeeded" ]; then
  PRODUCT_ID=$(echo "$TASK" | jq -r .data.product_id)
  curl -sS -H "Authorization: Bearer $HEDAAI_API_KEY" "$API/products/$PRODUCT_ID" \
    | jq -r '.data.images[].url, .data.listing_copy.title'
fi

MCP-Server (für KI-Agenten)

HedaAI stellt einen gehosteten Model Context Protocol-Server bereit, damit Agenten Produktbilder direkt generieren können:

claude mcp add --transport http hedaai https://hedaai.com/api/v1/mcp \
  --header "Authorization: Bearer $HEDAAI_API_KEY"

Die Generierung ist asynchron: Agenten rufen create_product_shoot auf (optional mit idempotency_key), pollen alle 30–60s get_task bis zum Endstatus und holen dann per get_product die Bild-URLs und den Listing-Text. Clients, die OAuth voraussetzen (z. B. claude.ai Custom Connectors), werden noch nicht unterstützt — API-Key-fähige Clients wie Claude Code, Cursor oder Agent-SDKs verwenden.

Preise

PositionPreis
Produkt-Shooting — 12 Bilder + Listing-Text$1.00, nur bei Erfolg berechnet
Startguthaben$2.00 (≈ 2 kostenlose Tasks, mit Wasserzeichen bis zur ersten Zahlung)
Guthaben aufladen$10–$1000 auf hedaai.com; ≥$50 +5% Bonus, ≥$100 +10%

Guthaben verfällt nie. Kein Abo. Der aktuelle Preis ist jederzeit über GET /v1/account abrufbar (price_per_task_cents).