Template-Based Image Generation with Genviso and BetterToken
A practical way to separate visual exploration from backend execution and turn a promising prompt into a versioned production template.
A good image is not yet a production workflow. For a single asset, you can rewrite a prompt several times, inspect the outputs, and choose one manually. With hundreds of SKUs, that habit becomes a long series of costly experiments. Every change to the light, camera angle, or material triggers another request, while the reason an image worked remains in one person's head.
Split the work into two loops. First, the team tests a visual direction and records the rules that can be repeated. Then the backend inserts business data into the approved template, sends requests, stores results, and handles errors. Creative exploration stays outside the production queue, and composition edits no longer require changes to server code.
Why prompt debugging in code gets out of control
Too many connected variables
An image model responds to the subject, environment, lighting, camera position, material, depth of field, and palette at the same time. A serum-bottle photograph changes substantially when you switch between:
- a straight-on view and a 45-degree top view;
- hard directional light and soft diffused light;
- reflective glass and a matte finish;
- travertine, metal, or seamless paper backgrounds;
- an 85 mm macro look and a wide-angle composition.
Change several variables together and you cannot tell which wording helped. Change them one at a time and the request count grows quickly. A backend using BetterToken can execute a template through the Image API, but starting the queue too early only reproduces an untested visual hypothesis at scale.
Each business task needs its own visual grammar
A product card needs a readable silhouette, controlled reflections, and room for layout. A 3D illustration has different constraints on shape and material. A social poster depends on hierarchy, contrast, and safe areas. One universal prompt usually accumulates contradictory adjectives.
It is more practical to keep several template families:
Each family defines its own required fields and acceptance criteria. The application selects a template by category and then fills it with data for the specific product or campaign.
Exploration and production need different rules
Exploration allows many variants and subjective comparison. Production needs a predictable contract, a template version, bounded retries, a job identifier, and an explicit acceptance result.
A fragile loop looks like this:
There is no point at which the visual decision becomes approved. As a result, every design discussion reaches into the backend and its task queue.
Workflow architecture: from visual hypothesis to a CMS asset
During visual exploration, the team uses Genviso to compare options in its visual prompt gallery, test composition, light, and style, and preserve the structure of a successful prompt. During server execution, the application uses BetterToken's OpenAI-compatible Base URL with the user's own API key, fills the variables, calls a currently available model, and records the output. The handoff between the two stages is a versioned Prompt Template—not a selected image or a set of verbal instructions.
To test this boundary before connecting a queue, create your own API key, run one control request with the approved template, and immediately reconcile its model, status, and actual charge in the Dashboard. This proves the server route without turning visual exploration into a stream of production requests.
Every transition should produce an artifact that can be checked:
Stage 1: turn the visual decision into a template
A starting structure for studio skincare photography could be:
The order and visual dimensions remain stable while their values change independently:
Before developers receive the template, record four more things:
- Required fields. Do not send a request without
subjectorcomposition. - Allowed values. If the camera angle has three approved options, use an enum instead of free-form CMS text.
- Forbidden combinations. Transparent packaging on a mirror may require a separate template.
- Acceptance criteria. The silhouette is readable, the logo is not distorted, the product is not cropped, and the background supports the final layout.
Keep the prompt beside a machine-readable contract:
The version in template_id makes a result reproducible. When a designer changes the lighting or composition, new jobs receive a new version while existing assets remain tied to the old one.
Stage 2: connect the template to the backend
For a first test, you need the official openai Python SDK, your own BetterToken API key, and a current model ID from the Image API documentation. Keep the key and model ID in the environment:
Never put a real key in source control, prompts, screenshots, or logs. In production, use a secret manager and separate keys for different applications or environments.
The following example renders the template, sends one request, and saves a PNG from b64_json:
The client.images.generate(...) call and b64_json decoding follow the current OpenAI Python SDK contract. The model ID stays in BETTERTOKEN_IMAGE_MODEL because available models and parameters should be checked before a run. A model change then does not require a rewrite of the Prompt Template or business logic.
A minimal batch-job loop
The following is deliberately explicit integration pseudocode. save_job, generate_image, and ApiError represent adapters for your storage and API client; they are not extra SDK methods. The important part is the sequence of states and decisions:
The local job_id links the SKU, template, and file; it does not make the remote request idempotent. After a timeout, leave the state as unknown, check the Dashboard by time and inspect object storage, and only then decide whether one resubmission is necessary. This keeps the queue from hiding a possible duplicate.
Troubleshooting order
What to add before batch generation
One successful file proves the basic route, not that the queue is ready for hundreds of jobs.
Validate data before the request
An empty material, unexpected markup in product_name, or free-form text in place of an approved palette changes the prompt. Check required fields, lengths, and allowed values before calling the model. Store the final prompt hash, template_id, and SKU identifier with the job.
Bound retries
A retry after a timeout can create another image even when the application missed the first response. Set a finite attempt count, add backoff, and assign a job_id to every run. Do not retry 400, 401, or model-configuration errors indefinitely; correct the data, key, or configuration first.
Separate technical and visual acceptance
HTTP 200 and a valid PNG prove technical success. Composition, product distortion, and brand fit are separate checks. The automated job stores the file and metadata; the next stage applies the template's visual criteria.
Reconcile the request with usage
After the control generation, locate the request in the Dashboard by time. Check the model, status, and charge; available usage fields cover input, output, and cache tokens. The Dashboard stores usage and spending metadata, not the full prompt or response. Use the current models and pricing page for budget planning, and use the request record for the actual test charge.
Example flow for a product catalog
For a store with several hundred SKUs, the job can move through this chain:
The prompt is now a versioned production object. You can see which template created a file, compare rejection rates by version, and roll back a poor change without rewriting the entire integration.
Pre-launch checklist
- The Prompt Template has been tested on representative products and difficult edge cases.
template_id, required variables, and acceptance criteria are defined.- The API key stays outside source code and logs.
- The model ID comes from the environment or configuration.
- One test request creates an openable file of the expected size.
- A 400/401 error triggers a data or configuration fix before another request.
- 429/5xx errors have a bounded retry policy.
- Every job maps to an SKU,
job_id, template version, and storage location. - Technical validation and visual acceptance are separate.
- The model, status, and test charge have been checked in the Dashboard.
How the role split improves collaboration
Genviso owns the interactive loop: finding a visual direction quickly, comparing prompts, and validating the template before developer handoff. BetterToken owns the server loop: API key management, the OpenAI-compatible connection, calling a currently available model, and recording usage. Both teams agree on one contract—a Prompt Template with variables, a version, and acceptance criteria.
To move an approved template into a working backend and verify its cost on one representative SKU, create your own API key, run the smallest request from the Image API reference, and check the model, status, and charge in the Dashboard before connecting the queue. This boundary keeps visual exploration interactive and production execution reproducible.