> ## Documentation Index
> Fetch the complete documentation index at: https://docs.animusai.co/llms.txt
> Use this file to discover all available pages before exploring further.

# Image Generation

> Generate character images, edit photos, and create videos with the Animus media generation API

## Base URL & Authentication

* **Base URL:** `https://api.animusai.co/v2`
* **Authentication:** `Authorization: Bearer <ANIMUS_API_KEY>`
* **Content type:** `application/json`

Every response includes a `generation_id` that you can use to poll status or fetch historical results later.

## Create a Generation

Use `POST /generation/create` to submit a single job. The API automatically infers the generation type from your payload:

* Provide `character_id` to trigger a character LoRA render (face/body LoRA and face swap are enabled by default).
* Provide `source_image_url` to run a Seedream photo edit.
* Provide both `source_image_url` and `convert_to_video: true` to turn an image into a short video clip.
* Omit both fields to default to text-to-image generation.

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.animusai.co/v2/generation/create \
    -H "Content-Type: application/json" \
    -H "Authorization: Bearer $ANIMUS_API_KEY" \
    -d '{
      "prompt": "Cinematic portrait lighting on Chloe standing in a neon street",
      "character_id": "char_123",
      "num_images": 1,
      "seed": 42
    }'
  ```

  ```python Python theme={null}
  import requests

  url = "https://api.animusai.co/v2/generation/create"
  payload = {
      "prompt": "Vintage postcard of a coastal lighthouse at sunrise",
      "source_image_url": "https://cdn.animusai.co/samples/lighthouse.png",
      "strength": 0.55,
      "guidance_scale": 8,
      "convert_to_video": False
  }

  resp = requests.post(
      url,
      headers={
          "Authorization": f"Bearer {ANIMUS_API_KEY}",
          "Content-Type": "application/json"
      },
      json=payload,
      timeout=30
  )
  print(resp.json())
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.animusai.co/v2/generation/create', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer ${process.env.ANIMUS_API_KEY}`
    },
    body: JSON.stringify({
      prompt: 'Slow push-in shot of a futuristic city plaza at dusk',
      convert_to_video: true,
      source_image_url: 'https://cdn.animusai.co/samples/plaza.png',
      num_images: 1
    })
  });

  const data = await response.json();
  console.log(data);
  ```
</CodeGroup>

### Request Body

| Field              | Type    | Default | Required | Notes                                                                                                                      |
| ------------------ | ------- | ------- | -------- | -------------------------------------------------------------------------------------------------------------------------- |
| `prompt`           | string  | —       | ✅        | Text prompt used for all generation types.                                                                                 |
| `num_images`       | integer | `1`     | ❌        | Values >1 are submitted as a batch (see below).                                                                            |
| `character_id`     | string  | `null`  | ❌        | Required for character-based renders. Automatically validates subscription access.                                         |
| `use_face_lora`    | boolean | `true`  | ❌        | Applies the character face LoRA. Only meaningful when `character_id` is set.                                               |
| `use_body_lora`    | boolean | `true`  | ❌        | Applies the character body LoRA.                                                                                           |
| `face_swap`        | boolean | `true`  | ❌        | Enables default face swap pass.                                                                                            |
| `source_image_url` | string  | `null`  | ❌        | Publicly reachable image URL for photo edits or video conversion. Automatically uploaded to temporary storage when needed. |
| `convert_to_video` | boolean | `false` | ❌        | Converts the output into a short MP4 clip. Requires `source_image_url`.                                                    |
| `group_id`         | string  | `null`  | ❌        | Attach the generation to an existing media group.                                                                          |
| `group_title`      | string  | auto    | ❌        | Title to use when creating a new group on the fly.                                                                         |

### Response

A successful submission returns a `GenerationResponse` object:

```json theme={null}
{
  "generation_id": "gen_5f0c2d8fbf8b",
  "group_id": "grp_a12f39e1",
  "status": "submitted",
  "message": "Character Generation job submitted successfully",
  "estimated_time": 30,
  "credits_deducted": 4,
  "remaining_balance": 96
}
```

Use `generation_id` to poll status or subscribe to webhooks in your own system. If the user lacks the required plan or credits, the endpoint returns an HTTP `402` with additional context.

## Track Generation Status

Use `GET /generation/status/{generation_id}` to retrieve the latest status, final media URLs, and performance metadata. The endpoint works for single renders and batches alike.

```bash theme={null}
curl "https://api.animusai.co/v2/generation/status/gen_5f0c2d8fbf8b" \
  -H "Authorization: Bearer $ANIMUS_API_KEY"
```

Example response after completion:

```json theme={null}
{
  "generation_id": "gen_5f0c2d8fbf8b",
  "group_id": "grp_a12f39e1",
  "generation_type": "character_generation",
  "status": "completed",
  "progress": 100,
  "result_urls": [
    "https://link.storjshare.io/raw/animus-prod/.../character_generation_gen_5f0c2d8fbf8b_0.png"
  ],
  "error": null,
  "created_at": "2024-07-01T15:04:55.101231",
  "prompt": "Cinematic portrait lighting on Chloe standing in a neon street",
  "performance_metadata": {
    "duration": 24.1,
    "queue_position": 0
  }
}
```

If you submit `num_images > 1`, the status payload includes aggregate counts so you can expose progress bars in your UI.

## Batch Submissions

Send multiple prompts (or the same prompt repeated) with `POST /generation/batch`. The API creates a shared group automatically and returns a single `batch_id` you can poll through the standard status endpoint.

```json theme={null}
{
  "prompts": [
    { "prompt": "Moody editorial portrait of Sora", "face_swap": true },
    { "prompt": "Profile shot of Sora in cinema lighting" },
    { "prompt": "Wide shot: Sora in a sci-fi hangar" }
  ],
  "character_id": "char_123",
  "group_title": "Sora editorial set"
}
```

The response reports how many jobs were accepted, any immediate validation errors, and the total credits deducted. Each generated asset will still appear in the group and status APIs.

## Organize Results with Groups

Every generation belongs to a **group** so you can fetch cohesive sessions or albums later.

* `GET /generation/groups` returns paginated groups for the authenticated organization.
* `GET /generation/groups/{group_id}` returns group metadata plus individual generations (with URLs) for galleries and download flows.

List groups:

```bash theme={null}
curl "https://api.animusai.co/v2/generation/groups?limit=20&offset=0" \
  -H "Authorization: Bearer $ANIMUS_API_KEY"
```

Typical response snippet:

```json theme={null}
{
  "groups": [
    {
      "group_id": "grp_a12f39e1",
      "title": "Chloe Neon Portraits",
      "group_type": "character_generation",
      "generation_count": 4,
      "preview_image_url": "https://link.storjshare.io/raw/.../character_generation_gen_5f0c2d8fbf8b_0.png",
      "created_at": "2024-07-01T15:04:50.102300",
      "updated_at": "2024-07-01T15:06:10.775220"
    }
  ],
  "pagination": {
    "limit": 20,
    "offset": 0,
    "returned": 1,
    "has_more": false
  }
}
```

Group detail:

```bash theme={null}
curl "https://api.animusai.co/v2/generation/groups/grp_a12f39e1?limit=12" \
  -H "Authorization: Bearer $ANIMUS_API_KEY"
```

```json theme={null}
{
  "group_id": "grp_a12f39e1",
  "title": "Chloe Neon Portraits",
  "generations": [
    {
      "generation_id": "gen_5f0c2d8fbf8b",
      "status": "completed",
      "result_urls": [
        "https://link.storjshare.io/raw/.../character_generation_gen_5f0c2d8fbf8b_0.png"
      ],
      "created_at": "2024-07-01T15:04:55.101231"
    }
  ],
  "pagination": {
    "limit": 12,
    "offset": 0,
    "returned": 1,
    "has_more": false
  }
}
```

## Cleanup Endpoints

You can let users curate storage directly from your product:

* `DELETE /generation/generations/{generation_id}` removes a specific job and purges all associated media from Storj.
* `DELETE /generation/groups/{group_id}` deletes the group, every generation inside it, and their assets in a single operation.

Both endpoints enforce organization scoping and return summaries of what was removed.

## Error Handling & Credits

* HTTP `402` responses indicate missing credits or subscription access for the requested character. The JSON payload includes `error`, `message`, and `character_id` fields so you can upsell or reroute the user.
* HTTP `409` responses appear when you attempt to delete a group while generations are still reconciling. Retry after active jobs finish.
* Most write operations deduct credits immediately and automatically refund them if submission fails before processing. Always check `remaining_balance` on the create responses to drive UX copy.

## Next Steps

* Use the status endpoint to power polling loops or push notifications.
* Combine group listings with your own asset selectors to build download or approval workflows.
* Pair these endpoints with the Animus SDK to offer one-click generation directly in chat experiences.
