Imagen API docs
Navigation menu
Reference

Copilot API

The Copilot API lets you apply prompt-based AI enhancements to individual photos after the initial edit completes. This is the same capability as the AI Assistant in the real estate web app. You send a natural-language instruction, and Imagen returns an enhanced version of the image. Edits chain, so you can build on previous results or reset to an earlier state.

Copilot is a general post-edit capability. Its endpoints sit on /v1/projects/ (no i2i prefix), so it works on top of any completed project regardless of how it was edited.

Export the project first

The project must have reached Completed status, and you must call export_project (Python) / exportProject (Node) on it before any Copilot call — including apply_copilot and get_ai_tools. Export prepares the edited versions Copilot builds on; without it these calls fail. You only need to export once per project.

Endpoints

MethodEndpointPurpose
POST/v1/projects/{uuid}/images/{filename}/copilotApply a prompt-based enhancement to one image
POST/v1/projects/{uuid}/images/{filename}/enhanceApply a preset enhancement to one image
GET/v1/projects/{uuid}/ai-toolsList the AI enhancement (preset) tools available for the project
DELETE/v1/projects/{uuid}/images/{filename}/copilotReset all Copilot edits on one image
POST/v1/projects/{uuid}/finalizeLock in Copilot edits and prepare the project for download

1. Send a prompt

POST /v1/projects/PROJECT_UUID/images/FILENAME/copilot

For the first call, set parent_version_id to null.

Copilot calls are synchronous

The endpoint waits for the enhancement to complete and returns the result directly. No polling required.

curl -X POST 'https://api.imagen-ai.com/v1/projects/$PROJECT_UUID/images/DSC_0001.JPEG/copilot' \
  --header 'x-api-key: $IMAGEN_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "instruction": "make the sky more blue",
    "parent_version_id": null,
    "project_source": "REGULAR"
  }'
# Export once before any Copilot call — required.
await client.export_project(project_uuid)

result = await client.apply_copilot(
    project_uuid,
    "DSC_0001.JPEG",
    "make the sky more blue",
)
version_id = result.version_id
// Export once before any Copilot call — required.
await client.exportProject(projectUuid);

const result = await client.applyCopilot(
  projectUuid,
  'DSC_0001.JPEG',
  'make the sky more blue'
);
const { versionId, enhancedImageUrl } = result;
import imagen "github.com/imagenai/imagen-ai-sdk/sdks/go"

// Export once before any Copilot call — required.
if err := client.ExportAndWait(ctx, projectUUID, nil); err != nil {
    log.Fatal(err)
}

result, _ := client.Copilot(ctx, projectUUID, "DSC_0001.JPEG", imagen.CopilotRequest{
    Instruction:   "make the sky more blue",
    ProjectSource: imagen.ProjectSourceRegular,
})
fmt.Println("version:", result.VersionID)
import java.net.URI;
import java.net.http.*;

var body = """
    {
        "instruction": "make the sky more blue",
        "parent_version_id": null,
        "project_source": "REGULAR"
    }
    """;
var request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.imagen-ai.com/v1/projects/" + projectUuid + "/images/DSC_0001.JPEG/copilot"))
    .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}/images/DSC_0001.JPEG/copilot")
req = Net::HTTP::Post.new(uri)
req['x-api-key'] = ENV['IMAGEN_API_KEY']
req['Content-Type'] = 'application/json'
req.body = {
  instruction: 'make the sky more blue',
  parent_version_id: nil,
  project_source: 'REGULAR',
}.to_json

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
version_id = JSON.parse(res.body)['version_id']
<?php
$url = 'https://api.imagen-ai.com/v1/projects/' . $projectUuid . '/images/DSC_0001.JPEG/copilot';
$ch = curl_init($url);
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([
    'instruction' => 'make the sky more blue',
    'parent_version_id' => null,
    'project_source' => 'REGULAR',
  ]),
]);
$response = curl_exec($ch);
curl_close($ch);
$version_id = json_decode($response, true)['version_id'];
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 {
    instruction = "make the sky more blue",
    parent_version_id = (int?)null,
    project_source = "REGULAR",
});
var content = new StringContent(payload, Encoding.UTF8, "application/json");
var response = await client.PostAsync(
    $"https://api.imagen-ai.com/v1/projects/{projectUuid}/images/DSC_0001.JPEG/copilot", content);
{
  "status": "SUCCESS",
  "version_id": 123,
  "enhanced_image_url": "https://<s3-presigned>"
}

Save the version_id. Pass it as parent_version_id on the next call to build on this result.

2. Chain edits

Each prompt creates a new version that builds on the previous one. Pass the prior version_id as parent_version_id. The response returns a new version_id such as 124. To branch from an earlier point, pass that earlier version_id instead. Subsequent edits will overwrite the branch you didn’t keep.

curl -X POST 'https://api.imagen-ai.com/v1/projects/$PROJECT_UUID/images/DSC_0001.JPEG/copilot' \
  --header 'x-api-key: $IMAGEN_API_KEY' \
  --header 'Content-Type: application/json' \
  --data '{
    "instruction": "brighten the interior",
    "parent_version_id": 123,
    "project_source": "REGULAR"
  }'
# parent_version_id chains this edit onto a previous version
result = await client.apply_copilot(
    project_uuid,
    "DSC_0001.JPEG",
    "brighten the interior",
    parent_version_id=123,
)
next_version_id = result.version_id  # e.g. 124
// parentVersionId chains this edit onto a previous version
const result = await client.applyCopilot(
  projectUuid,
  'DSC_0001.JPEG',
  'brighten the interior',
  { parentVersionId: 123 }
);
const nextVersionId = result.versionId; // e.g. 124
import imagen "github.com/imagenai/imagen-ai-sdk/sdks/go"

// ParentVersionID chains this edit onto a previous version
result, _ := client.Copilot(ctx, projectUUID, "DSC_0001.JPEG", imagen.CopilotRequest{
    Instruction:     "brighten the interior",
    ParentVersionID: 123,
    ProjectSource:   imagen.ProjectSourceRegular,
})
fmt.Println("next version:", result.VersionID) // e.g. 124
import java.net.URI;
import java.net.http.*;

var body = """
    {
        "instruction": "brighten the interior",
        "parent_version_id": 123,
        "project_source": "REGULAR"
    }
    """;
var request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.imagen-ai.com/v1/projects/" + projectUuid + "/images/DSC_0001.JPEG/copilot"))
    .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}/images/DSC_0001.JPEG/copilot")
req = Net::HTTP::Post.new(uri)
req['x-api-key'] = ENV['IMAGEN_API_KEY']
req['Content-Type'] = 'application/json'
req.body = {
  instruction: 'brighten the interior',
  parent_version_id: 123,
  project_source: 'REGULAR',
}.to_json

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
next_version_id = JSON.parse(res.body)['version_id']
<?php
$url = 'https://api.imagen-ai.com/v1/projects/' . $projectUuid . '/images/DSC_0001.JPEG/copilot';
$ch = curl_init($url);
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([
    'instruction' => 'brighten the interior',
    'parent_version_id' => 123,
    'project_source' => 'REGULAR',
  ]),
]);
$response = curl_exec($ch);
curl_close($ch);
$next_version_id = json_decode($response, true)['version_id'];
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 {
    instruction = "brighten the interior",
    parent_version_id = 123,
    project_source = "REGULAR",
});
var content = new StringContent(payload, Encoding.UTF8, "application/json");
var response = await client.PostAsync(
    $"https://api.imagen-ai.com/v1/projects/{projectUuid}/images/DSC_0001.JPEG/copilot", content);

Preset enhancement

POST .../images/{filename}/enhance applies a preset enhancement to a single image instead of a free-text instruction. It mirrors the /copilot call shape and also returns a new version. Use it when you want a fixed enhancement rather than a prompt.

3. List available AI tools

List the AI enhancement (preset) tools available for this project — the same presets the /enhance endpoint applies.

GET /v1/projects/PROJECT_UUID/ai-tools
curl 'https://api.imagen-ai.com/v1/projects/$PROJECT_UUID/ai-tools' \
  --header 'x-api-key: $IMAGEN_API_KEY'
# Export once before any Copilot call — required.
await client.export_project(project_uuid)

tools = await client.get_ai_tools(project_uuid)
for t in tools.prompts:
    print(t.enhancement_type, t.label)
// Export once before any Copilot call — required.
await client.exportProject(projectUuid);

const tools = await client.getAiTools(projectUuid);
for (const t of tools.prompts) {
  console.log(t.enhancementType, t.label);
}
import imagen "github.com/imagenai/imagen-ai-sdk/sdks/go"

// Export once before any Copilot call — required.
if err := client.ExportAndWait(ctx, projectUUID, nil); err != nil {
    log.Fatal(err)
}

tools, _ := client.GetAITools(ctx, projectUUID, imagen.ProjectSourceRegular)
for _, t := range tools.Prompts {
    fmt.Println(t.EnhancementType, t.Label)
}
import java.net.URI;
import java.net.http.*;

var request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.imagen-ai.com/v1/projects/" + projectUuid + "/ai-tools"))
    .header("x-api-key", System.getenv("IMAGEN_API_KEY"))
    .GET()
    .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}/ai-tools")
req = Net::HTTP::Get.new(uri)
req['x-api-key'] = ENV['IMAGEN_API_KEY']

res = Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
tools = JSON.parse(res.body)
<?php
$ch = curl_init('https://api.imagen-ai.com/v1/projects/' . $projectUuid . '/ai-tools');
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_HTTPHEADER => ['x-api-key: ' . getenv('IMAGEN_API_KEY')],
]);
$response = curl_exec($ch);
curl_close($ch);
$tools = json_decode($response, true);
using System.Net.Http;

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

var response = await client.GetAsync(
    $"https://api.imagen-ai.com/v1/projects/{projectUuid}/ai-tools");
var json = await response.Content.ReadAsStringAsync();

The response’s prompts array holds each tool’s enhancement_type (use it as the tool_id for /enhance), label, and enabled_for_batch flag.

4. Reset an image

Discard all Copilot edits on a single image and return it to its post-edit state.

DELETE /v1/projects/PROJECT_UUID/images/FILENAME/copilot
curl -X DELETE 'https://api.imagen-ai.com/v1/projects/$PROJECT_UUID/images/DSC_0001.JPEG/copilot' \
  --header 'x-api-key: $IMAGEN_API_KEY'
await client.reset_copilot(project_uuid, "DSC_0001.JPEG")
await client.resetCopilot(projectUuid, 'DSC_0001.JPEG');
import imagen "github.com/imagenai/imagen-ai-sdk/sdks/go"

err := client.ResetCopilot(ctx, projectUUID, "DSC_0001.JPEG", imagen.ProjectSourceRegular)
if err != nil {
    log.Fatal(err)
}
import java.net.URI;
import java.net.http.*;

var request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.imagen-ai.com/v1/projects/" + projectUuid + "/images/DSC_0001.JPEG/copilot"))
    .header("x-api-key", System.getenv("IMAGEN_API_KEY"))
    .DELETE()
    .build();
var response = HttpClient.newHttpClient()
    .send(request, HttpResponse.BodyHandlers.ofString());
require 'net/http'
require 'uri'

uri = URI("https://api.imagen-ai.com/v1/projects/#{project_uuid}/images/DSC_0001.JPEG/copilot")
req = Net::HTTP::Delete.new(uri)
req['x-api-key'] = ENV['IMAGEN_API_KEY']

Net::HTTP.start(uri.hostname, uri.port, use_ssl: true) { |http| http.request(req) }
<?php
$url = 'https://api.imagen-ai.com/v1/projects/' . $projectUuid . '/images/DSC_0001.JPEG/copilot';
$ch = curl_init($url);
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_CUSTOMREQUEST => 'DELETE',
  CURLOPT_HTTPHEADER => ['x-api-key: ' . getenv('IMAGEN_API_KEY')],
]);
curl_exec($ch);
curl_close($ch);
using System.Net.Http;

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

var response = await client.DeleteAsync(
    $"https://api.imagen-ai.com/v1/projects/{projectUuid}/images/DSC_0001.JPEG/copilot");

5. Finalize

Once you’re satisfied with all Copilot edits across the project, call /finalize to lock them in and prepare the output for download.

POST /v1/projects/PROJECT_UUID/finalize
curl -X POST 'https://api.imagen-ai.com/v1/projects/$PROJECT_UUID/finalize' \
  --header 'x-api-key: $IMAGEN_API_KEY'
result = await client.finalize_project(project_uuid)
for f in result.files_list:
    print(f.file_name, f.download_link)
const links = await client.finalizeProject(projectUuid);
// links is an array of final (upscaled) download URLs
import imagen "github.com/imagenai/imagen-ai-sdk/sdks/go"

result, _ := client.Finalize(ctx, projectUUID, imagen.ProjectSourceRegular)
for _, f := range result.FilesList {
    fmt.Println(f.FileName, f.DownloadLink)
}
import java.net.URI;
import java.net.http.*;

var request = HttpRequest.newBuilder()
    .uri(URI.create("https://api.imagen-ai.com/v1/projects/" + projectUuid + "/finalize"))
    .header("x-api-key", System.getenv("IMAGEN_API_KEY"))
    .POST(HttpRequest.BodyPublishers.noBody())
    .build();
var response = HttpClient.newHttpClient()
    .send(request, HttpResponse.BodyHandlers.ofString());
require 'net/http'
require 'uri'

uri = URI("https://api.imagen-ai.com/v1/projects/#{project_uuid}/finalize")
req = Net::HTTP::Post.new(uri)
req['x-api-key'] = ENV['IMAGEN_API_KEY']

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 . '/finalize');
curl_setopt_array($ch, [
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_POST => true,
  CURLOPT_HTTPHEADER => ['x-api-key: ' . getenv('IMAGEN_API_KEY')],
]);
curl_exec($ch);
curl_close($ch);
using System.Net.Http;

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

var response = await client.PostAsync(
    $"https://api.imagen-ai.com/v1/projects/{projectUuid}/finalize", null);

After finalizing, use the same download endpoint as your editing mode to retrieve the output files. Use Quickstart for profile-based projects, or Smart Editing for I2I projects.

Human revision is not yet in the API

Requesting an Imagen expert to review and re-edit a photo is available in the web app but is not yet supported via the API.