Zestio
Developer API

Zestio API Reference

Integrate AI-powered real estate image enhancement and virtual staging into your application.

Quick Start

1. Get an API Key

Sign up for an account, then create an API key in your dashboard Settings. Or create one via the API:

curl -X POST https://www.zestio.de/api/keys \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer ***" \
  -d '{"name": "My App"}'

# Response: { "secret": "zest_a1b2c3d4..." }

2. Make a Request

curl -X POST https://www.zestio.de/api/enhance \
  -H "Authorization: Bearer ***" \
  -H "Content-Type: application/json" \
  -d '{
    "image": "https://example.com/property.jpg",
    "enhancementType": "sky",
    "model": "auto"
  }'

Authentication

All API requests require an API key passed as a Bearer token:

API Key

Authorization: Bearer zest_x...

Create API keys in your dashboard Settings after signing up. Each key is prefixed zest_ and the full secret is only shown once.

API Key Management

GET/api/keys

List all your API keys (secrets are never returned)

Response

{
  "keys": [
    { "id": "uuid", "name": "My App", "key_prefix": "zest_a1b",
      "last_used_at": "...", "created_at": "...", "is_active": true }
  ]
}
POST/api/keys

Create a new API key. The secret is only returned once.

Parameters

NameTypeRequiredDescription
namestringNoLabel for the key (default: "Default Key")

Response

{
  "key": { "id": "uuid", "name": "My App", "key_prefix": "zest_a1b" },
  "secret": "zest_a1b2c3d4e5f6...",
  "warning": "Store this key securely. It cannot be retrieved again."
}
DELETE/api/keys

Revoke an API key

Parameters

NameTypeRequiredDescription
key_idstringYesThe key ID to revoke

Response

{ "success": true }

Image Enhancement

Enhance, transform, and clean up property photos.

POST/api/enhance
1-2 credits

Enhance a property image using AI. Supports sky replacement, season changes, decluttering, and more.

Parameters

NameTypeRequiredDescription
imagestringYesImage URL or base64 data URL
enhancementTypestringNoType of enhancement (see table). Default: "auto"
modelstringNoModel: "auto" (only option — diffusion models removed)
customPromptstringNoCustom prompt (overrides enhancementType)

Response

{
  "success": true,
  "output": "https://replicate.delivery/...",
  "creditsUsed": 1,
  "model": "auto"
}

Enhancement Types

TypeNameDescription
autoAuto EnhanceGeneral enhancement
skyBlue SkyClear sunny sky
sky_sunsetGolden SunsetWarm golden hour
sky_dramaticDramatic CloudsMoody cinematic sky
twilightVirtual TwilightBlue hour with warm glow
season_summerSummerLush green landscape
season_autumnAutumnGolden fall foliage
season_winterWinterPristine snow scene
curb_appealCurb AppealGreen lawn & landscaping
facade_refreshFacade RefreshClean painted exterior
object_removalObject RemovalRemove unwanted items
declutterDeclutterRemove personal items

Virtual Staging

Stage empty rooms with AI-generated furniture — or redesign furnished rooms.

POST/api/staging
2 credits

Apply virtual staging to a room photo (empty or furnished).

Parameters

NameTypeRequiredDescription
imagestringYesImage URL or base64 of the empty room
modelstringNo"interior-design" (default, fast), "precision" (mask-based, structure-preserving)
roomTypestringNoliving, bedroom, kitchen, dining, bathroom, office, basement, patio
furnitureStylestringNomodern, scandinavian, luxury, minimalist, industrial, bohemian, midcentury, farmhouse

Response

{
  "success": true,
  "output": "https://replicate.delivery/...",
  "model": "interior-design",
  "creditsUsed": 2,
  "creditsRemaining": 48
}

Staging Models

ModelCreditsDescription
interior-design2Best value, ControlNet-based — synchronous; empty and furnished rooms
precision2Structure-preserving: room layout, floor, windows and doors stay exactly as they are; walls/ceiling may be redesigned (paint, panels, lamp) — empty rooms get furnished, furniture is replaced (asynchronous)

Precision — how the process works

Precision redesigns the room — empty or furnished — in two zones: the fix zone (windows, doors, curtains, outdoor areas such as balcony/terrace) is taken 1:1 from the original; the edit zone (furniture, decor, walls, ceiling) may be redesigned — walls can be painted or fitted with wall panels, the ceiling can get a lamp. The floor is part of the mask (so furniture is drawn completely) and is then restored 1:1 from the original (floor restore) — the visible floor is always exactly the original, including shadows & furniture feet lying on top. Light switches/sockets are protected by a fixed prompt instruction (no ADE20K class → no mask protection). Processing runs asynchronously:

  1. POST /api/staging with model: "precision" → the response contains a jobId
  2. Class-based segmentation (SegFormer): windows, doors & outdoor areas are detected automatically (fix zone); the interior structure share is checked — pure exterior shots abort („Kein Innenraum erkannt")
  3. Zone mask: everything outside the fix zone becomes furnishable area — furniture, walls (paint/panels), ceiling (lamp) and floor (so furniture is drawn completely)
  4. Masked inpainting (flux-fill-pro): only the masked areas are redesigned — with instructions: keep the floor 1:1, switches/sockets unchanged, paint walls fresh, add a lamp
  5. Floor restore: a second SegFormer run detects the visible floor in the inpaint result and restores it pixel-exactly from the original — furniture & shadows stay on top
  6. Hard composite: fix zone (windows/doors/outdoor) pixel-exact from the original
  7. GET /api/staging/poll?jobId=<id> until status: "completed" (typical duration ~1–2.5 min)
# 1) Job starten
curl -X POST https://www.zestio.de/api/staging \
  -H "Authorization: Bearer ***" -H "Content-Type: application/json" \
  -d '{"image":"https://example.com/room.jpg","model":"precision","roomType":"living","furnitureStyle":"modern"}'

# → { "status": "processing", "stage": "mask", "jobId": "uuid", "maskPredictionId": "..." }

# 2) Fortschritt abfragen (alle ~5 s)
curl "https://www.zestio.de/api/staging/poll?jobId=uuid" -H "Authorization: Bearer ***"

# → { "status": "completed", "output": "https://...result.jpg", "stats": { "maskCoverage": 0.75, "structureCoverage": 0.35, "floorCoverage": 0.92 } }
#   Fehler: { "status": "failed", "error": "..." } — Rate-Limits (429) werden automatisch retried,
#   Außenaufnahmen ohne Innen-Struktur brechen mit klarer Meldung ab ("Kein Innenraum erkannt")

Progress: mask → inpaint → floor → completed. The job metadata carries the zone analysis (maskCoverage = edit zone/furnishable area, structureCoverage = detected interior structure (guard basis, exterior shots), protectedLabels = detected fix-zone classes, floorCoverage = share of the floor restored 1:1, floorPreserved = floor restore active) and the pixel difference outside the mask — your proof that windows & outdoor areas were left untouched. Jobs stuck without progress for more than 10 minutes are marked as failed automatically.

AI labelling (EU AI Act)

All AI-generated or AI-modified images (staging, sky replacement, object removal, videos, floor plans) carry a permanently burned-in official EU AI symbol (Art. 50(3) EU AI Act) with a label such as „Mit KI-Unterstützung (KI-modifiziert)". The symbol is part of the image itself (bottom right) — it cannot be removed or covered by a UI overlay. This keeps AI content clearly identifiable even after download or forwarding.

Also machine-readable in the XMP metadata: IPTC DigitalSourceType: trainedAlgorithmicMedia as well as comZestio:MarkingLabel / comZestio:MarkingVersion (namespace http://zestio.de/ns/ai-marking/1.0/). Assistive standard edits (brightness, colour correction, upscaling) count as the Art. 50(2) exception and are not labelled.

Errors & Rate Limits

HTTP Error Codes

StatusMeaning
400Missing or invalid parameters
401Missing or invalid authentication
402Insufficient credits (0 Credits — top up at /billing)
429Rate limit exceeded
500Server error or AI model failure

Rate Limits

Limits apply per API key/user per hour and are tiered by plan. Remaining requests are returned in the X-RateLimit-Remaining / X-RateLimit-Reset headers.

PlanLimitEndpoints
Public (no login)10/henhance, staging
Standard (signed in)100/henhance, staging, keys, MCP
Pro / Enterprise500/hall
Video (expensive calls)20/hgenerate_video
Webhooks1.000/hMCP, Feed

On 429 the API replies with Retry-After. Asynchronous jobs (Precision) retry rate-limit overruns automatically. Credits are deducted before execution; if the AI call fails (5xx, model error) they are refunded automatically — no double charge on retries.

Ready to integrate?

Sign up for a free account and get API access with 10 free credits.