---
title: "Real estate"
description: "Guide to editing real estate photos with Imagen: choosing an editing mode, the built-in presets, the real estate edit body, and what each AI tool does."
canonical: https://api-docs.imagen-ai.com/docs/guides/real-estate/
last-updated: 2026-08-27
---

# 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 in
[Onboarding](/docs/onboarding), including the
[supported file formats](/docs/onboarding#formats).

## Choose an editing mode

| | Profile-based editing | Smart Editing (I2I) |
| --- | --- | --- |
| **Endpoints** | `/v1/projects/...` | `/v1/i2i/projects/...` |
| **Needs an AI profile** | Yes. Choose one of Imagen's built-in presets or your own profile. | No. It uses Imagen's image-to-image model. |
| **Edit body** | Full tool set, including `profile_key`, `photography_type`, and `export`. | Includes `hdr_merge`, `perspective_correction`, `sky_replacement`, and `callback_url`. |
| **Upload** | Single PUT per file. | Single PUT per file, or multipart upload for large files. |
| **Status polling** | Two steps: poll `/edit/status`, then `/export/status`. | One step: poll the project. |
| **Output** | Full-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](/docs/reference/smart-editing)
when you want Imagen to detect the best editing style for your photos. Smart Editing uses the image-to-image model, which has no AI Profile and a simpler edit body.

## Profile-based editing

The profile-based flow uses the same `/v1/projects/...` endpoints as the
[Quickstart](/docs/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](/docs/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](/docs/quickstart#step-profiles).

The three built-in presets:

| Preset | JPEG `profile_key` | RAW `profile_key` |
| --- | --- | --- |
| Elegant Home | 178014 | 178011 |
| Modern Home | 472033 | JPEG uploads only |
| Natural Home | 333757 | 333755 |

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 edit body for real estate

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` to apply window pull. It's optional and defaults to `false`, so include it explicitly 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
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
  }'
```

```python
from imagen_sdk import EditOptions, PhotographyType

await client.start_editing(
    project_uuid,
    profile_key=333757,
    photography_type=PhotographyType.REAL_ESTATE,
    edit_options=EditOptions(
        hdr_merge=True,
        perspective_correction=True,
        sky_replacement=True,
        window_pull=True,
    ),
)
# schedule the JPEG export
await client.export_project(project_uuid)
```

```typescript
import { PhotographyType } from 'imagen-ai-sdk';

await client.startEditing(projectUuid, {
  profileKey: 333757,
  photographyType: PhotographyType.REAL_ESTATE,
  editOptions: {
    hdr_merge: true,
    perspective_correction: true,
    sky_replacement: true,
    window_pull: true,
  },
});
// schedule the JPEG export
await client.exportProject(projectUuid);
```

```go
import imagen "github.com/imagenai/imagen-ai-sdk/sdks/go"

edit := imagen.EditRequest{
    ProfileKey:      333757,
    PhotographyType: imagen.PhotographyTypeRealEstate,
}
edit.HDRMerge = imagen.Bool(true)
edit.PerspectiveCorrection = imagen.Bool(true)
edit.SkyReplacement = imagen.Bool(true)
edit.WindowPull = imagen.Bool(true)

if err := client.EditAndWait(ctx, projectUUID, edit, nil); err != nil {
    log.Fatal(err)
}
// schedule the JPEG export
if err := client.ExportAndWait(ctx, projectUUID, nil); err != nil {
    log.Fatal(err)
}
```

```java
import java.net.URI;

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());
```

```ruby
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
<?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);
```

```csharp
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.

> **When to choose a sky replacement template** When `sky_replacement=true`, pass `sky_replacement_template_id` to choose a specific sky. List the available templates with `GET&nbsp;/v1/projects/sky_replacement/templates`. 
Omit `sky_replacement_template_id` to apply your account's default template. 
When `sky_replacement=false`, make sure to omit `sky_replacement_template_id`. See [Quickstart](/docs/quickstart#step-edit) for more information.

> **Required setting for the Export field** In the real estate flow, the `export` field must be set as `export: true`.

## What each tool does

| Field | Effect on a real estate shoot |
| --- | --- |
| `hdr_merge` | Merges bracketed exposures into a single DNG. Set to `true` for bracketed shoots. |
| `perspective_correction` | Straightens vertical and horizontal lines in walls and doorways. Recommended for all interiors. |
| `window_pull` | Pulls highlight detail through interior windows so the exterior view is visible. Optional (defaults to `false`); set to `true` to apply it. |
| `sky_replacement` | Replaces blown-out sky with your account's default sky template. Use it for exteriors. See the callout above for choosing or omitting a sky replacement template. |

For full per-tool detail across all genres, see the
[AI tools reference](/docs/ai-tools).

## 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](/docs/quickstart#step-status).

You can skip polling entirely by passing a `callback_url` on `/edit`. See
[Callbacks](/docs/reference/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](/docs/reference/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](/docs/reference/copilot). It's the same capability as the AI Assistant in the real estate web app.
