GPT Image 2.5 Sunburst is wired into the FAL registry, the seed, Galleria and the workflow nodes. Four real generations were driven through the live UI by a browser agent — a text-to-image, a reference edit, a transparent cut-out, and a run from the workflow canvas node, which is a separate code path from Galleria. All seven hops of the generation path are exercised on both surfaces.
Three generations reached completed, none stuck in
queued. 15 credits charged each, three times over.
Galleria and the workflow canvas node, which are separate code paths. Six quality tiers and the new Background control render on each.
The credit figure is a placeholder and there is no production rollout script. Everything else is settled.
A request crosses seven hops. The provider call was proven first with direct requests; the remaining six were proven afterwards by driving the real interface, then checking the database and service logs rather than trusting the screen.
both surfaces: model picked, settings rendered, run
Verified
POST /api/v1/generations
Verified
generation:image:fal
Verified
registry lookup resolved the FAL path
Verified
fal.run/openai/gpt-image-2.5/sunburst/…
Verified
asset persisted, served back to the feed
Verified
credit_ledger · usage · 15.0000
Verified
Worth noting for anyone debugging later: nothing ever sat in
queued. FAL image models take the synchronous
fal.run path, which sidesteps the completion-webhook
failure mode that strands video generations when the gateway URL is wrong.
gpt-image-2 offers — and the
Background row, which no other model in the catalogue has.
The button quotes Generate (15 credits), read from the seeded row.
background: auto), the same lemon turned into a lime
through the edit endpoint, and a transparent cut-out. The cut-out is the
convincing one — it sits straight on the dark canvas with no white card
behind it. Credits read 9,999,855, down exactly 45 from 9,999,900.
The canvas is a different code path from Galleria — its own config, its own
defaults, its own execution file. Galleria passing proved nothing about it, so it was
tested separately. The node carries a risk Galleria does not: its dispatcher
destructures node data into an explicit allow-list and then rebuilds it into an
explicit object literal, so a key missing from either list arrives
undefined and falls silently back to a default.
POST /api/generations → 201
"config":{"image_size":"square_hd","quality":"low","background":"transparent","output_format":"png","num_images":1}
background arrives as
"transparent" — not "auto",
not absent. The silent-fallthrough failure mode did not occur; both allow-lists
carry the key.
square_hd, where Galleria produced
1024×768 from landscape_4_3. Same model, different
surface, different result — which is exactly why testing one could not stand in
for the other.
| Check | Observed | Result |
|---|---|---|
| Generation | 3e14f5b5… completed, bg=transparent, 17.3s | pass |
| Credits | 15.0000, quoted = charged | pass |
| Raw asset | 1024×1024 RGBA, 51.0% clear pixels | pass |
| Picker order | Sunburst first, GPT Image 2 second | pass |
The screen can lie. These lines are from vertex-ai.log and
show the path the registry resolved for each of the three runs.
[FAL Image] model=gpt-image-2.5-sunburst path=openai/gpt-image-2.5/sunburst/text-to-image edit=false images_in=0 [FAL Image] model=gpt-image-2.5-sunburst path=openai/gpt-image-2.5/sunburst/edit edit=true images_in=1 [FAL Image] model=gpt-image-2.5-sunburst path=openai/gpt-image-2.5/sunburst/text-to-image edit=false images_in=0
edit=true and swapped the path on its own, which is
exactly the implicit switch the registry is supposed to perform.
| Check | Observed | Result |
|---|---|---|
| Generations | 3 rows, all status = completed | pass |
| Stuck in queued | 0 | pass |
| Credits charged | 3 × usage 15.0000 in credit_ledger | pass |
| Picker order | Sunburst seq 5, GPT Image 2 seq 6 | pass |
| Gateway listener | cwd = this worktree, not a stale binary | pass |
background is the parameter new in 2.5. A screenshot of a
dark canvas cannot distinguish a real alpha channel from a dark fill, so the raw
stored assets were decoded and their pixels counted.
| Run | Encoding | Fully transparent pixels | Corner alpha |
|---|---|---|---|
| background = auto | 8-bit RGB | 0 (0.0%) | 255 |
| background = transparent | 8-bit RGBA | 364,388 (46.3%) | 0 |
background: transparent, returning RGBA.
Stem, highlight and contour survive the recolour untouched — the precision
editing Sunburst is chosen for.
Rather than pay for a generation per tier, deliberately invalid values were sent and
the provider's 422 responses read back. Each names its
accepted set, so every dropdown is validated at once, for free.
| Parameter | Accepted by FAL | Offered in UI | Match |
|---|---|---|---|
| quality | auto, low, medium, high, xhigh, max | all 6 | exact |
| background | auto, transparent, opaque | all 3 | exact |
| image_size | square_hd, square, portrait_4_3, portrait_16_9, landscape_4_3, landscape_16_9, auto | all 7 | exact |
| Check | Scope | Result |
|---|---|---|
| Go build | gateway, vertex-ai, go-queue | pass |
| Go vet | vertex-ai routes & internal | pass |
| Go test | ./routes/external/ | pass |
| ESLint | all 8 frontend files | pass |
| SQL parse | seed.sql into throwaway Postgres | pass |
| Sequence audit | no duplicates in image or video | pass |
The credit figure is a placeholder, not an agreed price.
Seeded at 15, derived from the repo's formula against the worst verified cost —
$0.211 at 1024px max. The vendor publishes no price for
4K combined with max, so that case may exceed a flat
rate. Both the model row and the cost row carry a marker to substitute the real
figure. If the true cost varies sharply by resolution, a
model_provider_costs row would track it better than a
flat default.
seed.sql is
development only. Shipping needs a scripts/prod-*.sql
that carries the sequence renumber, not merely the new row.
gpt-image-2 integration on the same provider. The ticket
has since been confirmed to contain exactly one thing — a link to
developers.openai.com/api/docs/models/gpt-image-2.5-sunburst.
The inference was right, and this is no longer an open question.
No image reference limits defined for model
gpt-image-2.5-sunburst — image_reference_limits
is {}, matching the other FAL models. No functional effect.
completed, so nothing exercises the error branch.
POST /api/workflows/{id}/session returns 400 and the
canvas silently refuses to add any node, for any model — no toast, no error.
frontend/stores/userStore.js:188 falls back
user.Email?.String || user.Email || "Unknown User"; when
Email is a Go sql.NullString,
the middle term is a truthy object, so an object is sent where a string
belongs and "Unknown User" is unreachable. Unrelated to
this change, latent in production where Clerk populates email. Worked around with
fixture data only.