---
title: Sets
description: "Generate a coordinated set of images sharing one visual system: packs and variants, one job per member, one status per set."
---

# Sets

A set groups two to eight labelled image prompts under one model and shared visual settings. Use it for carousel slides, ad variants or an exploration along a named axis. Each member remains its own job with its own credit hold and refund.

![A set fans out into independent image jobs and collects their outputs](../assets/diagrams/workflow-sets.svg)

<!-- gen:endpoints paths=/generate/set,/sets,/sets/{id} -->
| Method | Path | What it does |
| --- | --- | --- |
| [POST](../api/#tag/generate/post/generate/set) | `/generate/set` | Generate a coordinated set of image Outputs. |
| [GET](../api/#tag/sets/get/sets) | `/sets` | List sets in your current library, newest first. |
| [GET](../api/#tag/sets/get/sets/{id}) | `/sets/{id}` | Get a set with its jobs and Ready Outputs. |
<!-- /gen -->

## Choose a kind

### pack

| Property | Value |
| --- | --- |
| Value | `pack` |
| Default | Used when `kind` is omitted |
| Purpose | A coordinated collection, such as carousel slides or ad variants |
| Shared settings | Model, references, characters, location, saved style, brand kit, product and image settings |
| Member input | Its own `label` and `prompt` |

Repeat the visual rules each member must preserve in its prompt, and supply shared references and settings on the set. A shared visual system does not make one member's finished image the input to the next.

### variants

| Property | Value |
| --- | --- |
| Value | `variants` |
| Purpose | Explore a named axis, such as emotion or concept |
| Axis field | `axis`, a string up to 40 characters |
| Member labels | Name each direction so the resulting jobs and outputs remain identifiable |
| Billing | One independently priced image generation per accepted member |

## Submit a set

Use a label for each output and keep the same model and visual settings at the top level. These requests and responses are schema-built examples, not production captures. The installed CLI has no set-generation command; use the HTTP endpoint or a generated client.

```bash title="example — submit a pack"
$ curl --fail-with-body -sS https://api.nolgia.ai/v1/generate/set \
  -H "Authorization: Bearer $NOLGIA_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"model":"flux-pro","name":"Paper mountains","kind":"pack","members":[{"label":"Dawn","prompt":"A paper-cut mountain range at dawn, warm paper, blue shadows"},{"label":"Night","prompt":"A paper-cut mountain range at night, warm paper, blue shadows"}]}'
```

```json title="202 Accepted — example from OutputSet"
{
  "id": "b6a72f92-4e05-46b9-a28d-3c69c6d6e1e9",
  "name": "Paper mountains",
  "kind": "pack",
  "model": "flux-pro",
  "status": "generating",
  "labels": ["Dawn", "Night"],
  "members": [
    {
      "label": "Dawn",
      "prompt": "A paper-cut mountain range at dawn, warm paper, blue shadows",
      "sort_order": 0,
      "job": {
        "id": "6df58eed-0617-4f3c-8e87-e2f28d05e37d",
        "user_id": "75976388-3210-42e6-9b39-bf6290a15d4c",
        "model": "flux-pro",
        "modality": "image",
        "status": "queued",
        "created_at": "2026-09-21T04:00:00Z",
        "updated_at": "2026-09-21T04:00:00Z"
      }
    },
    {
      "label": "Night",
      "prompt": "A paper-cut mountain range at night, warm paper, blue shadows",
      "sort_order": 1,
      "job": {
        "id": "a432a04c-cbf1-4cfe-8fdc-ebd4d7a504e8",
        "user_id": "75976388-3210-42e6-9b39-bf6290a15d4c",
        "model": "flux-pro",
        "modality": "image",
        "status": "queued",
        "created_at": "2026-09-21T04:00:01Z",
        "updated_at": "2026-09-21T04:00:01Z"
      }
    }
  ],
  "created_at": "2026-09-21T04:00:00Z",
  "updated_at": "2026-09-21T04:00:01Z"
}
```

<!-- gen:fields schema=OutputSet -->
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `id` | string | Yes |  |
| `name` | string | Yes |  |
| `kind` | `OutputSetKind` | Yes |  |
| `axis` | string | No |  |
| `preset_slug` | string | No |  |
| `project_id` | string | No |  |
| `model` | string | Yes |  |
| `shared` | object | No |  |
| `labels` | array of string | Yes |  |
| `status` | `OutputSetStatus` | Yes |  |
| `members` | array of `OutputSetMember` | Yes |  |
| `problems` | array of `OutputSetProblem` | No |  |
| `created_at` | string | Yes |  |
| `updated_at` | string | Yes |  |
<!-- /gen -->

<!-- gen:fields schema=OutputSetMember -->
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `label` | string | Yes |  |
| `prompt` | string | Yes |  |
| `sort_order` | integer | Yes |  |
| `job` | `Job` | Yes |  |
| `asset` | `Asset` | No |  |
<!-- /gen -->

The nested `job` uses the [Job response](./jobs.html#submit-a-request). When it succeeds, the member's `asset` contains the ready output. Store the set id for the group and the member job ids for progress or support.

### Request fields

<!-- gen:fields schema=GenerateSetRequest -->
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `confirmation_token` | string | No | Optional proof that this exact request and price were shown to the customer, from `POST /jobs/cost`.… |
| `model` | `ImageModel` | Yes |  |
| `members` | array of `OutputSetMemberInput` | Yes |  |
| `name` | string | No |  |
| `kind` | `OutputSetKind` | No |  |
| `axis` | string | No | A named axis for a variants set, such as emotion or concept. |
| `preset_slug` | string, nullable | No |  |
| `project_id` | string | No |  |
| `tags` | array of string | No |  |
| `reference_asset_ids` | array of string, nullable | No |  |
| `face_reference_asset_id` | string, nullable | No |  |
| `face_check_consent` | boolean, nullable | No | Applied to every member exactly as on `POST /generate/image`: records your consent to the face identity check for the `face_reference_asset_id` photo (once per photo; it stays recorded for later requests).… |
| `character_ids` | array of string, nullable | No |  |
| `location_id` | string, nullable | No |  |
| `brand_kit_id` | string, nullable | No |  |
| `product_id` | string, nullable | No |  |
| `style_id` | string, nullable | No |  |
| `negative_prompt` | string, nullable | No |  |
| `aspect_ratio` | `ImageAspectRatio` | No |  |
| `quality` | string, nullable | No |  |
| `render_quality` | one of `auto`, `low`, `medium`, `high`, `xhigh`, `max` | No |  |
<!-- /gen -->

<!-- gen:fields schema=OutputSetMemberInput -->
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `label` | string | Yes |  |
| `prompt` | string | Yes |  |
<!-- /gen -->

`members` must contain 2–8 entries; each label is 1–40 characters and each prompt 1–4,000 characters. `kind` defaults to `pack`. A `variants` request can name its axis. `confirmation_token` comes from a set quote through `POST /jobs/cost`; it covers the exact set request and price.

## Poll the outputs

`GET /sets/{id}` returns an `OutputSet` with the latest jobs and ready assets. The following command projects the fields a progress list needs; the JSON is a schema-built completed example of that projection.

```bash title="example — poll and project the member outcomes"
$ curl -sS "https://api.nolgia.ai/v1/sets/$SET_ID" -H "Authorization: Bearer $NOLGIA_TOKEN"
```

```json title="200 OK — example projection of OutputSet"
{
  "id": "b6a72f92-4e05-46b9-a28d-3c69c6d6e1e9",
  "status": "ready",
  "outputs": [
    {
      "label": "Dawn",
      "job_id": "6df58eed-0617-4f3c-8e87-e2f28d05e37d",
      "status": "succeeded",
      "asset_id": "c87cf95c-2975-4d88-976c-234060f95fbf"
    },
    {
      "label": "Night",
      "job_id": "a432a04c-cbf1-4cfe-8fdc-ebd4d7a504e8",
      "status": "succeeded",
      "asset_id": "d25f50c0-ced7-4baa-ad9a-03bdb31766fd"
    }
  ],
  "problems": null
}
```

| Projected field | Source | Meaning |
| --- | --- | --- |
| `id` | `OutputSet.id` | Group identifier to retain and poll. |
| `status` | `OutputSet.status` | Overall progress; values below. |
| `outputs[].label` | `members[].label` | Your name for the requested output. |
| `outputs[].job_id` | `members[].job.id` | The individual generation to follow. |
| `outputs[].status` | `members[].job.status` | That member's job outcome. |
| `outputs[].asset_id` | `members[].asset.id` | Ready library output; the projection gives `null` before it exists. |
| `problems` | `OutputSet.problems` | Refused labels when present; absent when no member was refused. |

### Set status

| `OutputSetStatus` | Meaning | Next action |
| --- | --- | --- |
| `generating` | Member jobs are still running. | Poll the same set. |
| `ready` | All outputs are ready. | Read or download the member assets. |
| `partial` | Some jobs failed. | Keep successful outputs; inspect failed jobs and any refused labels. |
| `failed` | All jobs failed. | Inspect each job's failure and refund before deciding what to resubmit. |

### List previous sets

`GET /sets` reads sets in your current library, newest first. `project_id` filters by project; `limit` accepts 1–100 and defaults to 25. The empty result below is a schema-built example.

```bash title="example — list sets"
$ curl --fail-with-body -sS 'https://api.nolgia.ai/v1/sets?limit=25' \
  -H "Authorization: Bearer $NOLGIA_TOKEN"
```

```json title="200 OK — example from OutputSetList"
{"sets": []}
```

<!-- gen:fields schema=OutputSetList -->
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `sets` | array of `OutputSet` | Yes |  |
<!-- /gen -->

<!-- gen:params op=listSets -->
| Parameter | In | Required | Description |
| --- | --- | --- | --- |
| `project_id` | query | No |  |
| `limit` | query | No | Maximum sets to return, 25 when omitted. |
<!-- /gen -->

## Partial acceptance and billing

If a later member is refused, accepted members keep running and further members are not submitted. The set's `problems` array lists refused labels, each with its HTTP status and detail. A refusal is different from a member that was accepted and later failed: the latter has a job whose `failure.code` and `failure.credits_refunded` describe the outcome.

<!-- gen:fields schema=OutputSetProblem -->
| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `label` | string | Yes |  |
| `status` | integer | Yes |  |
| `detail` | string | Yes |  |
<!-- /gen -->

| Outcome | What to inspect | Credit result |
| --- | --- | --- |
| Member accepted | Its nested `job` | Its own hold, settled on completion. |
| Member refused at submission | `problems[].label`, `status`, `detail` | No accepted generation for that member; accepted siblings continue. |
| Accepted member fails | `members[].job.failure` | Its recorded refund is independent of siblings; read `credits_refunded`. |
| Remaining members were not submitted | Compare requested labels with `members` and `problems` | No job or hold for the unsubmitted work. |

> [!WARNING]
> `Idempotency-Key` on `POST /generate/set` is ignored per member. Do not retry the whole set to repair a partial result: first inspect the returned set and its accepted jobs, or you can create and pay for another copy of work already running.

Quote a set before submission using `POST /jobs/cost` with `kind: set` and the full `set` request. That quote covers the run's members at their shared image settings. It does not make acceptance atomic or pool their refunds.

## Next steps

:::cards
- [Asynchronous: submit and poll](./jobs.html): Follow an individual member's job and read its failure outcome.
- [Pricing and credits](./billing.html): Quote the whole run and reconcile member charges and refunds.
:::
