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.

Project must be completed first

The project must have reached Completed status before you can use Copilot on its images.

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-toolsFetch full version history for all images in 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"
  }'
import httpx, os

body = {
    "instruction": "make the sky more blue",
    "parent_version_id": None,
    "project_source": "REGULAR",
}
async with httpx.AsyncClient() as http:
    resp = await http.post(
        f"https://api.imagen-ai.com/v1/projects/{project_uuid}/images/DSC_0001.JPEG/copilot",
        headers={"x-api-key": os.environ["IMAGEN_API_KEY"]},
        json=body,
    )
    version_id = resp.json()["version_id"]
const res = await fetch(
  `https://api.imagen-ai.com/v1/projects/${projectUuid}/images/DSC_0001.JPEG/copilot`,
  {
    method: 'POST',
    headers: {
      'x-api-key': process.env.IMAGEN_API_KEY!,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      instruction: 'make the sky more blue',
      parent_version_id: null,
      project_source: 'REGULAR',
    }),
  }
);
const { version_id, enhanced_image_url } = await res.json();
import (
    "bytes"
    "encoding/json"
    "net/http"
    "os"
)

body, _ := json.Marshal(map[string]any{
    "instruction": "make the sky more blue",
    "parent_version_id": nil,
    "project_source": "REGULAR",
})
url := "https://api.imagen-ai.com/v1/projects/" + projectUUID + "/images/DSC_0001.JPEG/copilot"
req, _ := http.NewRequestWithContext(ctx, http.MethodPost, url, 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 = """
    {
        "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"
  }'
import httpx, os

body = {
    "instruction": "brighten the interior",
    "parent_version_id": 123,
    "project_source": "REGULAR",
}
async with httpx.AsyncClient() as http:
    resp = await http.post(
        f"https://api.imagen-ai.com/v1/projects/{project_uuid}/images/DSC_0001.JPEG/copilot",
        headers={"x-api-key": os.environ["IMAGEN_API_KEY"]},
        json=body,
    )
    next_version_id = resp.json()["version_id"]  # e.g. 124
const res = await fetch(
  `https://api.imagen-ai.com/v1/projects/${projectUuid}/images/DSC_0001.JPEG/copilot`,
  {
    method: 'POST',
    headers: {
      'x-api-key': process.env.IMAGEN_API_KEY!,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      instruction: 'brighten the interior',
      parent_version_id: 123,
      project_source: 'REGULAR',
    }),
  }
);
const { version_id } = await res.json(); // e.g. 124
import (
    "bytes"
    "encoding/json"
    "net/http"
    "os"
)

body, _ := json.Marshal(map[string]any{
    "instruction": "brighten the interior",
    "parent_version_id": 123,
    "project_source": "REGULAR",
})
url := "https://api.imagen-ai.com/v1/projects/" + projectUUID + "/images/DSC_0001.JPEG/copilot"
req, _ := http.NewRequestWithContext(ctx, http.MethodPost, url, 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 = """
    {
        "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. Check version history

Retrieve the full version tree for all images in a project.

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'
import httpx, os

async with httpx.AsyncClient() as http:
    resp = await http.get(
        f"https://api.imagen-ai.com/v1/projects/{project_uuid}/ai-tools",
        headers={"x-api-key": os.environ["IMAGEN_API_KEY"]},
    )
    adjustments = resp.json()  # ProjectAdjustmentsResponse — version history per image
const res = await fetch(
  `https://api.imagen-ai.com/v1/projects/${projectUuid}/ai-tools`,
  { headers: { 'x-api-key': process.env.IMAGEN_API_KEY! } }
);
const adjustments = await res.json();
import (
    "net/http"
    "os"
)

req, _ := http.NewRequestWithContext(ctx, http.MethodGet,
    "https://api.imagen-ai.com/v1/projects/"+projectUUID+"/ai-tools", nil)
req.Header.Set("x-api-key", os.Getenv("IMAGEN_API_KEY"))

resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
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) }
adjustments = 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);
$adjustments = 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();

Returns a ProjectAdjustmentsResponse with version history per image.

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'
import httpx, os

async with httpx.AsyncClient() as http:
    await http.delete(
        f"https://api.imagen-ai.com/v1/projects/{project_uuid}/images/DSC_0001.JPEG/copilot",
        headers={"x-api-key": os.environ["IMAGEN_API_KEY"]},
    )
await fetch(
  `https://api.imagen-ai.com/v1/projects/${projectUuid}/images/DSC_0001.JPEG/copilot`,
  {
    method: 'DELETE',
    headers: { 'x-api-key': process.env.IMAGEN_API_KEY! },
  }
);
import (
    "net/http"
    "os"
)

url := "https://api.imagen-ai.com/v1/projects/" + projectUUID + "/images/DSC_0001.JPEG/copilot"
req, _ := http.NewRequestWithContext(ctx, http.MethodDelete, url, nil)
req.Header.Set("x-api-key", os.Getenv("IMAGEN_API_KEY"))

resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
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'
import httpx, os

async with httpx.AsyncClient() as http:
    await http.post(
        f"https://api.imagen-ai.com/v1/projects/{project_uuid}/finalize",
        headers={"x-api-key": os.environ["IMAGEN_API_KEY"]},
    )
await fetch(
  `https://api.imagen-ai.com/v1/projects/${projectUuid}/finalize`,
  {
    method: 'POST',
    headers: { 'x-api-key': process.env.IMAGEN_API_KEY! },
  }
);
import (
    "net/http"
    "os"
)

url := "https://api.imagen-ai.com/v1/projects/" + projectUUID + "/finalize"
req, _ := http.NewRequestWithContext(ctx, http.MethodPost, url, nil)
req.Header.Set("x-api-key", os.Getenv("IMAGEN_API_KEY"))

resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
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.