Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.photalabs.com/llms.txt

Use this file to discover all available pages before exploring further.

This guide walks you through the core Phota API workflow: authenticate, create a profile, wait for training, and run your first edit, generation, and enhancement.
Prerequisites: You need an API key from the Developer Portal. All requests require the X-API-Key header.
1

Authenticate

Every request must include your API key in the X-API-Key header. Verify your key works by listing your profiles:
curl https://api.photalabs.com/v1/phota/profiles/ids \
  -H "X-API-Key: YOUR_API_KEY"
You should receive a JSON response with your profiles (empty if you haven’t created any yet):
{
  "profiles": []
}
2

Create a profile

A profile represents a subject whose identity you want to preserve across edits and generations. Provide to publicly accessible image URLs of the subject (person, dog, or cat):
curl -X POST https://api.photalabs.com/v1/phota/profiles/add \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "image_urls": [
      "https://example.com/photo1.jpg",
      "https://example.com/photo2.jpg",
      "https://example.com/photo3.jpg"
    ],
    "tag": "user_abc123"
  }'
The response includes the new profile ID:
{
  "profile_id": "abc123"
}
Training starts immediately and runs asynchronously. The profile is not ready for use until training completes. See the Profiles guide for tips on choosing good training photos.
3

Poll for training status

Check the profile status until it reaches READY:
curl https://api.photalabs.com/v1/phota/profiles/abc123/status \
  -H "X-API-Key: YOUR_API_KEY"
Possible status values:
StatusMeaning
IN_PROGRESSTraining is still running. Poll again in a few seconds.
READYTraining completed. The profile is ready for edits.
ERRORTraining failed. Check the message field for details.
4

Edit an image

Once the profile is READY, you can reference it in an edit request. Provide input images as base64 strings or public URLs, along with a text prompt. You can refer to a profile inline in the prompt with [[profile_id]] and/or list candidate profiles in the profile_ids field — either mechanism is enough on its own:
curl -X POST https://api.photalabs.com/v1/phota/edit \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Make [[abc123]] smile wider",
    "images": ["https://example.com/photo.jpg"],
    "profile_ids": ["abc123"],
    "aspect_ratio": "1:1",
    "resolution": "4K",
    "num_output_images": 2,
    "output_format": "jpg"
  }'
This example shows both mechanisms for illustration. In practice you’d pick one — see the Profiles guide for when each approach is best.
The response contains the output images as base64-encoded strings (default response_mode: "bytes"):
{
  "images": ["/9j/4AAQ...", "/9j/4AAQ..."],
  "download_urls": [],
  "known_subjects": {
    "counts": {
      "abc123": 2
    }
  }
}
You can control the output aspect ratio (e.g. "9:16"), resolution (up to "4K"), and output_format ("png" or "jpg") on every request. Set response_mode: "urls" to receive signed CDN download URLs instead of base64 bytes.
Add "base_model": "gpt-image-2" (or another supported value) to pick which image model powers the request. Defaults to "nb2" (Nano Banana 2). See Base model selection.
To get download URLs instead of base64 bytes, set response_mode: "urls":
curl
curl -X POST https://api.photalabs.com/v1/phota/edit \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Make [[abc123]] smile wider",
    "images": ["https://example.com/photo.jpg"],
    "profile_ids": ["abc123"],
    "resolution": "4K",
    "num_output_images": 2,
    "output_format": "jpg",
    "response_mode": "urls"
  }'
{
  "images": [],
  "download_urls": [
    "https://cache-cdn.photalabs.com/20260408/abc123.jpg?token=...&expires=...",
    "https://cache-cdn.photalabs.com/20260408/def456.jpg?token=...&expires=..."
  ],
  "known_subjects": {
    "counts": {
      "abc123": 2
    }
  }
}
5

Generate an image

You can also generate images from scratch — no input image needed. Reference profiles directly in the prompt using [[profile_id]] syntax:
curl -X POST https://api.photalabs.com/v1/phota/generate \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "A professional portrait shot of [[abc123]] on a tropical beach at sunset",
    "num_output_images": 2,
    "output_format": "jpg"
  }'
The response format is the same as /edit:
{
  "images": ["/9j/4AAQ...", "/9j/4AAQ..."],
  "download_urls": [],
  "known_subjects": {
    "counts": {
      "abc123": 2
    }
  }
}
Generation is non-deterministic — request multiple variations with num_output_images and let the user pick the best one.
The /generate endpoint does not accept images or profile_ids. Reference profiles in the prompt with [[profile_id]] syntax instead. If you need to transform an existing photo, use /edit.
/generate also accepts base_model — same set of values as /edit, same default of "nb2". See Base model selection.
6

Enhance an image

Enhancement improves a photo automatically — no prompt needed:
curl -X POST https://api.photalabs.com/v1/phota/enhance \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "image": "https://example.com/photo.jpg",
    "profile_ids": ["abc123"],
    "num_output_images": 2,
    "output_format": "jpg"
  }'
/enhance does not accept base_model. Enhancement is pinned to Nano Banana 2 at 2K — see Pricing.

Next steps

Authentication

Learn about API key management and best practices.

Use cases

See detailed examples of each capability with visual previews.

Profiles guide

Deep-dive into profiles, identity preservation, and prompt syntax.

Pricing

Per-image and per-profile rates.