# Advanced Image Generation

Advanced generation features: reference images, aliases, flows, and regeneration. For basic generation, see [image-generation.md](image-generation.md).

All endpoints require Project Key authentication via `X-API-Key` header.

---

## Reference Images

Use existing images as style or content references for generation.

### Using References

Add `referenceImages` array to your generation request:

```json
{
  "prompt": "A product photo with the logo in the corner",
  "referenceImages": ["@brand-logo", "@product-style"]
}
```

References can be:
- **Project aliases**: `@logo`, `@brand-style`
- **Flow aliases**: `@hero` (with flowId context)
- **Technical aliases**: `@last`, `@first`, `@upload`
- **Image UUIDs**: `550e8400-e29b-41d4-a716-446655440000`

### Auto-Detection from Prompt

Aliases in the prompt are automatically detected and used as references:

```json
{
  "prompt": "Create a banner using @brand-logo with blue background"
}
// @brand-logo is auto-detected and added to referenceImages
```

### Reference Limits

| Constraint | Limit |
|------------|-------|
| Max references | 3 images |
| Max file size | 5MB per image |
| Supported formats | PNG, JPEG, WebP |

### Response with References

```json
{
  "data": {
    "id": "550e8400-...",
    "prompt": "Create a banner using @brand-logo",
    "referencedImages": [
      { "imageId": "7c4ccf47-...", "alias": "@brand-logo" }
    ],
    "referenceImages": [
      {
        "id": "7c4ccf47-...",
        "storageUrl": "http://...",
        "alias": "@brand-logo"
      }
    ]
  }
}
```

---

## Alias Assignment

Assign aliases to generated images for easy referencing.

### Project-Scoped Alias

Use `alias` parameter to assign a project-wide alias:

```json
{
  "prompt": "A hero banner image",
  "alias": "@hero-banner"
}
```

The output image will be accessible via `@hero-banner` anywhere in the project.

### Flow-Scoped Alias

Use `flowAlias` parameter to assign a flow-specific alias:

```json
{
  "prompt": "A hero image variation",
  "flowId": "550e8400-...",
  "flowAlias": "@best"
}
```

The alias `@best` is only accessible within this flow's context.

### Alias Format

| Rule | Description |
|------|-------------|
| Prefix | Must start with `@` |
| Characters | Alphanumeric, underscore, hyphen |
| Pattern | `@[a-zA-Z0-9_-]+` |
| Max length | 50 characters |
| Examples | `@logo`, `@hero-bg`, `@image_1` |

### Reserved Aliases

These aliases are computed automatically and cannot be assigned:

| Alias | Description |
|-------|-------------|
| `@last` | Most recently generated image in flow |
| `@first` | First generated image in flow |
| `@upload` | Most recently uploaded image in flow |

### Override Behavior

When assigning an alias that already exists:
- The **new image gets the alias**
- The **old image loses the alias** (alias set to null)
- The old image is **not deleted**, just unlinked

---

## 3-Tier Alias Resolution

Aliases are resolved in this order of precedence:

### 1. Technical Aliases (Highest Priority)

Computed on-the-fly, require flow context:

```
GET /api/v1/images/@last?flowId=550e8400-...
```

| Alias | Returns |
|-------|---------|
| `@last` | Last generated image in flow |
| `@first` | First generated image in flow |
| `@upload` | Last uploaded image in flow |

### 2. Flow Aliases

Stored in flow's `aliases` JSONB field:

```
GET /api/v1/images/@hero?flowId=550e8400-...
```

Different flows can have the same alias pointing to different images.

### 3. Project Aliases (Lowest Priority)

Stored in image's `alias` column:

```
GET /api/v1/images/@logo
```

Global across the project, unique per project.

### Resolution Example

```
// Request with flowId
GET /api/v1/images/@hero?flowId=abc-123

// Resolution order:
// 1. Is "@hero" a technical alias? No
// 2. Does flow abc-123 have "@hero" in aliases? Check flows.aliases JSONB
// 3. Does any image have alias = "@hero"? Check images.alias column
```

---

## Flow Integration

Flows organize related generations into chains.

### Lazy Flow Creation

When `flowId` is not provided, a pending flow ID is generated:

```json
// Request
{
  "prompt": "A red car"
  // No flowId
}

// Response
{
  "data": {
    "id": "gen-123",
    "flowId": "flow-456"  // Auto-generated, flow record not created yet
  }
}
```

The flow record is created when:
- A second generation uses the same `flowId`
- A `flowAlias` is assigned to any generation in the flow

### Eager Flow Creation

When `flowAlias` is provided, the flow is created immediately:

```json
{
  "prompt": "A hero banner",
  "flowAlias": "@hero-flow"
}
```

### No Flow Association

To explicitly create without flow association:

```json
{
  "prompt": "A standalone image",
  "flowId": null
}
```

### flowId Behavior Summary

| Value | Behavior |
|-------|----------|
| `undefined` (not provided) | Auto-generate pendingFlowId, lazy creation |
| `null` (explicitly null) | No flow association |
| `"uuid-string"` | Use provided ID, create flow if doesn't exist |

---

## Regeneration

### Regenerate Generation

Recreate an image using the exact same parameters:

```
POST /api/v1/generations/:id/regenerate
```

**Behavior:**
- Uses exact same prompt, aspect ratio, references
- **Preserves** output image ID and URL
- Works regardless of current status
- No request body needed

**Response:** Same as original generation with new image

### Update and Regenerate

Use PUT to modify parameters with smart regeneration:

```
PUT /api/v1/generations/:id
```

```json
{
  "prompt": "A blue car instead",
  "aspectRatio": "1:1"
}
```

**Smart Behavior:**

| Changed Field | Triggers Regeneration |
|---------------|----------------------|
| `prompt` | Yes |
| `aspectRatio` | Yes |
| `flowId` | No (metadata only) |
| `meta` | No (metadata only) |

### Flow Regenerate

Regenerate the most recent generation in a flow:

```
POST /api/v1/flows/:id/regenerate
```

**Behavior:**
- Finds the most recent generation in flow
- Regenerates with exact same parameters
- Returns error if flow has no generations

---

## Flow Management

### List Flows

```
GET /api/v1/flows
```

**Query Parameters:**

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `limit` | number | `20` | Results per page (max: 100) |
| `offset` | number | `0` | Pagination offset |

**Response:**

```json
{
  "data": [
    {
      "id": "flow-456",
      "projectId": "project-123",
      "aliases": { "@hero": "img-789", "@best": "img-abc" },
      "generationCount": 5,
      "imageCount": 7,
      "createdAt": "2025-11-28T10:00:00.000Z"
    }
  ],
  "pagination": { "limit": 20, "offset": 0, "total": 3, "hasMore": false }
}
```

### Get Flow

```
GET /api/v1/flows/:id
```

Returns flow with computed counts and aliases.

### List Flow Generations

```
GET /api/v1/flows/:id/generations
```

Returns all generations in the flow, ordered by creation date (newest first).

### List Flow Images

```
GET /api/v1/flows/:id/images
```

Returns all images in the flow (generated and uploaded).

### Update Flow Aliases

```
PUT /api/v1/flows/:id/aliases
```

```json
{
  "aliases": {
    "@hero": "image-id-123",
    "@best": "image-id-456"
  }
}
```

**Behavior:** Merges with existing aliases (does not replace all).

### Remove Flow Alias

```
DELETE /api/v1/flows/:id/aliases/:alias
```

Example: `DELETE /api/v1/flows/flow-456/aliases/@hero`

### Delete Flow

```
DELETE /api/v1/flows/:id
```

**Cascade Behavior:**
- Flow record is **hard deleted**
- All generations in flow are **hard deleted**
- Images **without** project alias: **hard deleted** with MinIO cleanup
- Images **with** project alias: **kept**, but `flowId` set to null

---

## Full Request Example

```json
// POST /api/v1/generations
{
  "prompt": "A professional product photo using @brand-style and @product-template",
  "aspectRatio": "1:1",
  "autoEnhance": true,
  "enhancementOptions": { "template": "product" },
  "flowId": "campaign-flow-123",
  "alias": "@latest-product",
  "flowAlias": "@hero",
  "meta": { "campaign": "summer-2025" }
}
```

**What happens:**
1. `@brand-style` and `@product-template` resolved and used as references
2. Prompt enhanced using "product" template
3. Generation created in flow `campaign-flow-123`
4. Output image assigned project alias `@latest-product`
5. Output image assigned flow alias `@hero` in the flow
6. Custom metadata stored

---

## Response Fields (Additional)

| Field | Type | Description |
|-------|------|-------------|
| `flowId` | string | Associated flow UUID |
| `alias` | string | Project-scoped alias (on outputImage) |
| `referencedImages` | array | Resolved references: `[{ imageId, alias }]` |
| `referenceImages` | array | Full image details of references |

---

## Error Codes

| HTTP Status | Code | Description |
|-------------|------|-------------|
| 400 | `ALIAS_FORMAT_CHECK` | Alias must start with @ |
| 400 | `RESERVED_ALIAS` | Cannot use technical alias |
| 404 | `ALIAS_NOT_FOUND` | Referenced alias doesn't exist |
| 404 | `FLOW_NOT_FOUND` | Flow does not exist |

---

## See Also

- [Basic Generation](image-generation.md) - Simple generation
- [Image Upload](images-upload.md) - Upload with aliases
- [Live URLs](live-url.md) - CDN and live generation
