---
title: Iterate on outputs | FLORA API
description: Re-run a Technique using previous outputs as image references.
---

After generating a grid, the natural next step is *“give me more like #4 and #7.”* FLORA Techniques accept image URLs as inputs, so prior outputs can drive new runs — no re-uploading required.

**What you’ll build:** a function that takes a list of “favorite” output URLs and generates N new variants anchored to them.

## TypeScript

```
import Flora from '@flora-ai/flora';


const client = new Flora({ apiKey: process.env.FLORA_API_KEY });


async function iterate(
  slug: string,
  favorites: string[],   // URLs from a previous run
  directive: string,
  count = 5,
) {
  const run = await client.techniques.runs.create(slug, {
    inputs: [
      { id: 'directive', type: 'text', value: directive },
      ...favorites.map((url, i) => ({
        id: `reference_${i}`,
        type: 'imageUrl' as const,
        value: url,
      })),
      { id: 'count', type: 'text', value: String(count) },
    ],
    mode: 'async',
  });


  return pollUntilDone(run.run_id, slug);
}


async function pollUntilDone(runId: string, slug: string) {
  while (true) {
    const result = await client.techniques.runs.retrieve(runId, { techniqueId: slug });
    if (result.status === 'completed') return result.outputs.map((o: any) => o.url);
    if (result.status === 'failed') throw new Error(result.error_message);
    await new Promise((r) => setTimeout(r, 2000));
  }
}


// Use it
const previousGrid = [
  'https://ik.imagekit.io/flora/run_abc/output_3.png',  // #4
  'https://ik.imagekit.io/flora/run_abc/output_6.png',  // #7
];


const moreLikeThese = await iterate(
  'thumbnail-v3',
  previousGrid,
  'Lock the lighting and composition from the references. Explore copy and color.',
  10,
);
```

## Match input names to your Technique

The input IDs above (`directive`, `reference_0`, `reference_1`, `count`) are illustrative. Real Techniques expose their own input schema. **Always inspect first:**

```
const technique = await client.techniques.retrieve('thumbnail-v3');
console.log(technique.inputs);
// [
//   { id: 'brief', type: 'text', name: 'Brief' },
//   { id: 'image_references', type: 'imageUrl[]', name: 'Reference images', multiple: true },
//   { id: 'count', type: 'text', name: 'Number of outputs' },
// ]
```

If a Technique accepts an array input (`type: 'imageUrl[]'`), pass all references under one input:

```
inputs: [
  { id: 'image_references', type: 'imageUrl[]', value: favorites },
]
```

If it accepts individual reference slots (`reference_0`, `reference_1`), pass each separately as in the example above.

## Composing iterations

This pattern composes cleanly with itself. Iterate, pick new favorites, iterate again:

```
let pool = await generateGrid('Smart living, simple. Warm minimalism.', 9);


for (let round = 0; round < 3; round++) {
  const favorites = await pickFavorites(pool); // your own UI / CLI prompt
  pool = await iterate('thumbnail-v3', favorites, 'tighten composition', 6);
}
```

## URL lifetime

Output URLs are long-lived but not permanent — re-running this script weeks later with the same URLs may fail. For long-lived workflows, either:

1. Re-generate from the original brief.
2. Download favorites and re-upload as [permanent assets](/recipes/upload-an-asset/index.md), then reference those URLs.

## Related

- **[Generate a grid](/recipes/generate-a-grid/index.md)** — produce the initial pool of options.
- **[Upload an asset](/recipes/upload-an-asset/index.md)** — make a URL permanent.
- **[Batch from a CSV](/recipes/batch-from-csv/index.md)** — scale this pattern across many inputs.
