Imagen API docs
Navigation menu
Guides

Real estate

Imagen eliminates hours of busywork from real estate post-production. Photographers upload listing photos and receive fully edited JPEGs back, complete with sky replacement, perspective correction, window pull, and an automatically applied HDR merge. The real estate API supports two editing modes:

  • Profile-based editing: Apply a trained AI Profile to your photos. Choose one of Imagen’s built-in presets or your own Personal or Talent AI Profile.
  • Smart Editing: Use Imagen’s image-to-image model. No AI profile required.

Both modes share the same setup: sign-up, API key, and supported file formats. They use different endpoint namespaces. The setup is covered once in Onboarding, including the supported file formats and the file-family rule.

Choosing an editing mode

Profile-based editingSmart Editing (I2I)
Endpoints/v1/projects/.../v1/i2i/projects/...
Needs an AI profileYes. Choose one of Imagen’s built-in presets or your own profile.No. It uses Imagen’s image-to-image model.
Edit bodyFull tool set, including profile_key, photography_type, and export.Includes hdr_merge, perspective_correction, sky_replacement, and callback_url.
UploadSingle PUT per file.Single PUT per file, or multipart upload for large files.
Status pollingTwo steps: poll /edit/status, then /export/status.One step: poll the project.
OutputFull-resolution edited JPEGs, exported automatically.Edited JPEGs. No separate export step.

Use profile-based editing when you want consistent, full-resolution results that match a preset or your own profile. Use Smart Editing when you want the image-to-image model with no profile and a simpler edit body.

Profile-based editing

The profile-based flow uses the same /v1/projects/... endpoints as the Quickstart: create a project, request upload links, upload, edit, poll status, then download. This guide covers what’s specific to real estate. For the create, upload, poll, and download mechanics, follow Quickstart.

Built-in presets

For real estate editing, choose exactly one of two categories for profile_key: a built-in preset, or a Personal or Talent AI Profile from the Imagen desktop app. To list your own profiles, see Quickstart.

The three built-in presets:

PresetJPEG profile_keyRAW profile_key
Elegant Home178014178011
Modern Home472033JPEG uploads only
Natural Home333757333755

Pick the JPEG variant when all uploaded images are JPEGs. Pick the RAW variant when any uploaded image is a RAW. Modern Home works with JPEG uploads only. Use Elegant Home or Natural Home for RAW shoots.

The real-estate edit body

For real estate, explicitly send every tool flag. Three fields must be set to fixed values for the flow to work end-to-end:

  • photography_type: Set to "REAL_ESTATE".
  • window_pull: Set to true. This field is always on for the real estate flow.
  • export: Set to true. This schedules a JPEG export automatically after the edit completes.
POST /v1/projects/PROJECT_UUID/edit
curl -X POST 'https://api.imagen-ai.com/v1/projects/$PROJECT_UUID/edit' \
  --header 'x-api-key: $IMAGEN_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "profile_key": 333757,
    "hdr_merge": true,
    "perspective_correction": true,
    "sky_replacement": true,
    "window_pull": true,
    "photography_type": "REAL_ESTATE",
    "export": true,
    "crop": false,
    "straighten": false,
    "portrait_crop": false,
    "headshot_crop": false,
    "subject_mask": false,
    "smooth_skin": false
  }'
import httpx, os

body = {
    "profile_key": 333757,
    "hdr_merge": True,
    "perspective_correction": True,
    "sky_replacement": True,
    "window_pull": True,
    "photography_type": "REAL_ESTATE",
    "export": True,  # part of the edit body — schedules the JPEG export
}
async with httpx.AsyncClient() as http:
    await http.post(
        f"https://api.imagen-ai.com/v1/projects/{project_uuid}/edit",
        headers={"x-api-key": os.environ["IMAGEN_API_KEY"]},
        json=body,
    )
const body = {
  profile_key: 333757,
  hdr_merge: true,
  perspective_correction: true,
  sky_replacement: true,
  window_pull: true,
  photography_type: 'REAL_ESTATE',
  export: true,
};
await fetch(`https://api.imagen-ai.com/v1/projects/${projectUuid}/edit`, {
  method: 'POST',
  headers: {
    'x-api-key': process.env.IMAGEN_API_KEY!,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify(body),
});
import (
    "bytes"
    "encoding/json"
    "net/http"
    "os"
)

body, _ := json.Marshal(map[string]any{
    "profile_key": 333757,
    "hdr_merge": true,
    "perspective_correction": true,
    "sky_replacement": true,
    "window_pull": true,
    "photography_type": "REAL_ESTATE",
    "export": true,
})
req, _ := http.NewRequestWithContext(ctx, http.MethodPost,
    "https://api.imagen-ai.com/v1/projects/"+projectUUID+"/edit",
    bytes.NewReader(body),
)
req.Header.Set("x-api-key", os.Getenv("IMAGEN_API_KEY"))
req.Header.Set("Content-Type", "application/json")

resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
import java.net.URI;
import java.net.http.*;

var body = """
    {
        "profile_key": 333757,
        "hdr_merge": true,
        "perspective_correction": true,
        "sky_replacement": true,
        "window_pull": true,
        "photography_type": "REAL_ESTATE",
        "export": true
    }
    """;
var request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.imagen-ai.com/v1/projects/" + projectUuid + "/edit"))
    .header("x-api-key", System.getenv("IMAGEN_API_KEY"))
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(body))
    .build();
var response = HttpClient.newHttpClient()
    .send(request, HttpResponse.BodyHandlers.ofString());
require 'net/http'
require 'json'
require 'uri'

uri = URI("https://api.imagen-ai.com/v1/projects/#{project_uuid}/edit")
req = Net::HTTP::Post.new(uri)
req['x-api-key'] = ENV['IMAGEN_API_KEY']
req['Content-Type'] = 'application/json'
req.body = {
  profile_key: 333757,
  hdr_merge: true,
  perspective_correction: true,
  sky_replacement: true,
  window_pull: true,
  photography_type: 'REAL_ESTATE',
  export: true,
}.to_json

Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
<?php
$ch = curl_init('https://api.imagen-ai.com/v1/projects/' . $projectUuid . '/edit');
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_POST => true,
  CURLOPT_HTTPHEADER => [
    'x-api-key: ' . getenv('IMAGEN_API_KEY'),
    'Content-Type: application/json',
  ],
  CURLOPT_POSTFIELDS => json_encode([
    'profile_key' => 333757,
    'hdr_merge' => true,
    'perspective_correction' => true,
    'sky_replacement' => true,
    'window_pull' => true,
    'photography_type' => 'REAL_ESTATE',
    'export' => true,
  ]),
]);
curl_exec($ch);
curl_close($ch);
using System.Net.Http;
using System.Text;
using System.Text.Json;

using var client = new HttpClient();
client.DefaultRequestHeaders.Add("x-api-key",
    Environment.GetEnvironmentVariable("IMAGEN_API_KEY"));

var payload = JsonSerializer.Serialize(new {
    profile_key = 333757,
    hdr_merge = true,
    perspective_correction = true,
    sky_replacement = true,
    window_pull = true,
    photography_type = "REAL_ESTATE",
    export = true,
});
var content = new StringContent(payload, Encoding.UTF8, "application/json");
await client.PostAsync(
    $"https://api.imagen-ai.com/v1/projects/{projectUuid}/edit", content);

The flags crop, straighten, portrait_crop, headshot_crop, subject_mask, and smooth_skin are part of the broader Imagen API but the real estate flow does not use them. Send them as false to match the web app, or omit them. The server treats unset tool flags as false. The cURL example above sends them explicitly. The other languages omit them.

Sky template selection is not exposed via the API

When sky_replacement=true, omit sky_replacement_template_id. Your account’s default template is applied automatically. When sky_replacement=false, omit it entirely. Template selection isn’t available through the API for the real estate flow.

On the export field

The export field is functional but isn’t shown in the live API reference schema. The real estate flow relies on export: true. Set it as shown above.

What each tool does

FieldEffect on a real estate shoot
hdr_mergeMerges bracketed exposures into a single DNG. Set to true for bracketed shoots.
perspective_correctionStraightens vertical and horizontal lines in walls and doorways. Recommended for all interiors.
window_pullPulls highlight detail through interior windows so the exterior view is visible. It’s always on for the real estate flow.
sky_replacementReplaces blown-out sky with your account’s default sky template. Use it for exteriors.

For full per-tool detail across all genres, see the AI tools reference.

Status and timing

Because export=true schedules an export after the edit, the profile-based flow has two statuses to wait on: poll /edit/status until Completed, then poll /export/status until Completed. The export status endpoint returns an error until the export has been scheduled (which happens automatically once the edit completes), so poll edit status first, then switch to export status. The polling mechanics and code samples are documented in Quickstart.

You can skip polling entirely by passing a callback_url on /edit. See Callbacks.

Timing expectation

A 42-image project with 3-frame brackets takes 30-40 minutes end-to-end. 6-frame brackets roughly double that.

Smart Editing alternative

If you’d rather skip profiles and use the image-to-image model, the Smart Editing flow takes a minimal edit body and returns JPEGs as soon as the project reports Completed. There’s no separate export step. HDR-merged output is downsized in Smart Editing. Use the profile-based flow above for full-resolution HDR.

Refine with Copilot

After a project reaches Completed in either mode, you can apply prompt-based enhancements to individual photos with the Copilot API. It’s the same capability as the AI Assistant in the real estate web app.