API Dokumentation

Programmieren Sie Zugriff auf Immopix-Funktionen. Bearbeiten Sie Bilder, verwalten Sie Properties und integrieren Sie KI-Optimierungen in Ihren Workflow.

Hinweis

Die API erfordert ein aktives Abonnement. Trial-Benutzer und Nutzer mit nur Credit-Paketen haben keinen API-Zugang.

Authentifizierung

Die Immopix API verwendet Token-basierte Authentifizierung. Ihr API-Token kann in den Account-Einstellungen generiert und widerrufen werden.

Senden Sie Ihren Token im Authorization Header bei jeder Anfrage:

Authorization: Token ihr_api_token

Fehlerbehandlung

Bei Fehlern gibt die API ein JSON-Objekt mit einem error Feld zurück:

{
  "error": {
    "code": "insufficient_credits",
    "message": "Keine Credits verfügbar"
  }
}

Fehler-Codes

Code Status Beschreibung
invalid_token401Token fehlt oder ist ungültig
subscription_required403API erfordert aktives Abonnement
insufficient_credits402Keine Credits verfügbar
invalid_preset400Ungültiger Preset-Key
image_too_large400Bild überschreitet 20MB
image_required400Weder image_base64 noch image_url angegeben
rate_limit_exceeded429Rate Limit erreicht
conflict400presets und custom_prompt gleichzeitig angegeben
not_found404Ressource nicht gefunden

Paginierung

Listen-Endpoints unterstützen Cursor-basierte Paginierung mit limit (Standard: 20, Max: 100) und cursor Parametern.

{
  "data": [...],
  "pagination": {
    "has_more": true,
    "next_cursor": "abc123"
  }
}

Rate Limits

60 Anfragen pro Minute pro Token. Bei Überschreitung: 429 Status mit Retry-After Header.

Bild-Limits: Max 20MB, Formate JPEG/PNG/WebP, Max 8192x8192 Pixel


Tutorial: Bild bearbeiten

Der typische Workflow: Bild hochladen, Job abwarten, Ergebnis abrufen.

Python

import base64
import time
import requests

API_TOKEN = "ihr_api_token"
headers = {"Authorization": f"Token {API_TOKEN}"}

# 1. Bild hochladen
with open("foto.jpg", "rb") as f:
    image_base64 = base64.b64encode(f.read()).decode()

response = requests.post(
    "https://immopix.ai/api/v1/photos/edit",
    headers=headers,
    json={
        "image_base64": image_base64,
        "presets": "auto"  # oder: ["sunshine", "optimize"]
    }
)
job = response.json()
job_id = job["job_id"]
print(f"Job gestartet: {job_id}")

# 2. Job-Status abfragen (Polling)
while True:
    response = requests.get(
        f"https://immopix.ai/api/v1/jobs/{job_id}",
        headers=headers
    )
    job = response.json()

    if job["status"] == "completed":
        print(f"Fertig: {job['result_url']}")
        break
    elif job["status"] == "failed":
        print(f"Fehler: {job['error_message']}")
        break

    time.sleep(2)

cURL

# 1. Bild hochladen
curl -X POST "https://immopix.ai/api/v1/photos/edit" \
  -H "Authorization: Token ihr_api_token" \
  -H "Content-Type: application/json" \
  -d '{
    "image_url": "https://example.com/foto.jpg",
    "presets": "auto"
  }'

# Response: {"job_id": "job_abc123", "status": "pending", ...}

# 2. Job-Status abfragen
curl "https://immopix.ai/api/v1/jobs/job_abc123" \
  -H "Authorization: Token ihr_api_token"

Eigene Anweisungen (custom_prompt)

Statt Presets können Sie auch eigene Anweisungen übergeben:

curl -X POST "https://immopix.ai/api/v1/photos/edit" \
  -H "Authorization: Token ihr_api_token" \
  -H "Content-Type: application/json" \
  -d '{
    "image_url": "https://example.com/foto.jpg",
    "custom_prompt": "Rasen grün machen, Himmel blau, Mülltonnen entfernen"
  }'

Tipp: Nutzen Sie Webhooks anstelle von Polling, um bei Job-Abschluss benachrichtigt zu werden.


Properties

Properties sind Container für Fotos einer Immobilie.

GET /api/v1/properties

Listet alle Properties auf.

{
  "data": [
    {
      "id": "prp_abc123",
      "name": "Musterstraße 42",
      "created_at": "2024-01-15T10:30:00Z",
      "photo_count": 12
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  }
}
POST /api/v1/properties

Erstellt eine neue Property.

Request Body

name *Name der Property
{
  "id": "prp_abc123",
  "name": "Musterstraße 42",
  "created_at": "2024-01-15T10:30:00Z",
  "photo_count": 0
}
GET /api/v1/properties/{id}

Property-Details mit verschachtelter Foto-Liste.

{
  "id": "prp_abc123",
  "name": "Musterstraße 42",
  "created_at": "2024-01-15T10:30:00Z",
  "photo_count": 3,
  "photos": [
    {
      "id": "pht_xyz789",
      "title": "Wohnzimmer",
      "image_type": "indoor",
      "thumbnail_url": "https://..."
    }
  ]
}
PATCH /api/v1/properties/{id}

Aktualisiert eine Property. Parameter: name

DELETE /api/v1/properties/{id}

Löscht Property und alle zugehörigen Fotos. Unwiderruflich.

Photos

GET /api/v1/properties/{id}/photos

Listet alle Fotos einer Property auf.

{
  "data": [
    {
      "id": "pht_xyz789",
      "title": "Wohnzimmer",
      "image_type": "indoor",
      "current_url": "https://...",
      "thumbnail_url": "https://...",
      "created_at": "2024-01-15T10:30:00Z"
    }
  ],
  "pagination": {
    "has_more": false,
    "next_cursor": null
  }
}
GET /api/v1/photos/{id}

Foto-Details mit Revision-History und URLs.

{
  "id": "pht_xyz789",
  "title": "Wohnzimmer",
  "image_type": "indoor",
  "current_url": "https://...",
  "thumbnail_url": "https://...",
  "revisions": [
    {
      "id": "rev_abc123",
      "version": 1,
      "is_original": false,
      "url": "https://...",
      "created_at": "2024-01-15T10:35:00Z"
    }
  ],
  "created_at": "2024-01-15T10:30:00Z"
}
Hinweis: Bild-URLs sind signiert und laufen nach 60 Minuten ab.
POST /api/v1/photos/edit

Sendet ein Bild zur KI-Optimierung.

Request Body

image_base64Base64-kodierte Bilddaten
image_urlURL zum Bild (öffentlich zugänglich)
photo_idBestehendes Foto erneut bearbeiten
presetsArray von Preset-Keys oder "auto"
custom_promptEigene Anweisungen (max. 1000 Zeichen). Kernvorgaben werden automatisch angewendet.
property_idMit Property verknüpfen
aspect_ratio"auto" (Standard) oder spezifisch
lock_camera_angleKamerawinkel beibehalten (boolean)
room_typeRaumtyp für Möblierung. Werte: living_room, bedroom, kitchen, bathroom, kids_room, dining_room, hallway, office, garage, basement. Ohne Angabe wird automatisch erkannt.

Sie müssen image_base64, image_url oder photo_id angeben.

presets und custom_prompt sind gegenseitig ausschließend – verwenden Sie eines von beiden. Ohne Angabe werden Standard-Presets verwendet.

Verfügbare Presets

Verwenden Sie "auto" für automatische Erkennung, oder wählen Sie spezifische Presets:

Outdoor
  • optimize – Belichtung optimieren
  • sunshine – Wetter aufbessern
  • declutter – Störendes entfernen
Indoor
  • optimize_indoor – Belichtung optimieren
  • details – Deko & Details
  • staging – Virtuell möblieren

Response

{
  "job_id": "job_abc123",
  "photo_id": "pht_xyz789",
  "status": "pending"
}
DELETE /api/v1/photos/{id}

Löscht Foto und alle Revisionen.

Jobs

GET /api/v1/jobs/{job_id}

Job-Status abfragen. Status: pending | processing | completed | failed

{
  "job_id": "job_abc123",
  "photo_id": "pht_xyz789",
  "status": "completed",
  "presets": ["sunshine", "optimize"],
  "result_url": "https://...",
  "width": 1920,
  "height": 1080,
  "error_message": null,
  "created_at": "2024-01-15T10:30:00Z"
}
result_url, width, height nur bei status: "completed". error_message nur bei status: "failed".

Webhooks

Webhook-URLs werden in den Account-Einstellungen konfiguriert. Events: job.completed, job.failed

{
  "event": "job.completed",
  "job": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "photo_id": "pht_xyz789",
    "status": "completed",
    "presets": ["sunshine", "optimize"],
    "result_url": "https://...",
    "width": 1920,
    "height": 1080,
    "created_at": "2024-01-15T10:30:00Z"
  }
}
Retry-Policy: 3 Versuche mit exponentiellem Backoff (1min, 5min, 30min). Nach 3 Fehlschlägen wird der Webhook deaktiviert.

Signatur-Verifizierung

Jeder Webhook enthält einen X-Immopix-Signature Header (HMAC-SHA256).

Python
import hmac
import hashlib

def verify_signature(payload: bytes, signature: str, secret: str) -> bool:
    expected = hmac.new(secret.encode(), payload, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature)

# In Ihrem Webhook-Handler:
signature = request.headers.get("X-Immopix-Signature")
if not verify_signature(request.data, signature, WEBHOOK_SECRET):
    return "Invalid signature", 401
Node.js
const crypto = require('crypto');

function verifySignature(payload, signature, secret) {
  const expected = crypto.createHmac('sha256', secret).update(payload).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}

Credits

Die API verwendet dasselbe Credit-System wie die Web-Oberfläche. Details finden Sie auf unserer Preisseite. Bei einem insufficient_credits-Fehler sind Ihre Credits aufgebraucht.