Iterate on outputs
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
Section titled “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.runId, 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.errorMessage); await new Promise((r) => setTimeout(r, 2000)); }}
// Use itconst 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,);func iterate( ctx context.Context, c *flora.Client, slug string, favorites []string, directive string, count int,) ([]string, error) { inputs := []flora.TechniqueRunNewParamsInput{ {ID: "directive", Type: "text", Value: directive}, {ID: "count", Type: "text", Value: fmt.Sprint(count)}, } for i, url := range favorites { inputs = append(inputs, flora.TechniqueRunNewParamsInput{ ID: fmt.Sprintf("reference_%d", i), Type: "imageUrl", Value: url, }) }
run, err := c.Techniques.Runs.New(ctx, slug, flora.TechniqueRunNewParams{ Inputs: inputs, Mode: flora.TechniqueRunNewParamsModeAsync, }) if err != nil { return nil, err } return pollUntilDone(ctx, c, slug, run.RunID)}Match input names to your Technique
Section titled “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
Section titled “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
Section titled “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:
- Re-generate from the original brief.
- Download favorites and re-upload as permanent assets, then reference those URLs.
Related
Section titled “Related”- Generate a grid — produce the initial pool of options.
- Upload an asset — make a URL permanent.
- Batch from a CSV — scale this pattern across many inputs.