API Integration Patterns for GPT-Image2 Generation: A Complete Developer Guide
GPT-Image2 uses a RESTful client-server architecture built on the Apimart service layer and Supabase authentication, offering synchronous task creation, asynchronous polling, and webhook callbacks for image generation workflows.
The freestylefly/awesome-gpt-image-2 repository implements a production-ready image generation API that bridges front-end applications to OpenAI's image models. Understanding the API integration patterns for GPT-Image2 generation requires examining how the system handles authentication, task queuing, and result delivery across multiple endpoints.
Core Request Flow
The integration follows a six-step pipeline that decouples the initial request from the computationally expensive generation process.
In api/generate-image.js, the server exposes a POST endpoint that accepts JSON payloads containing the prompt, style, and dimensions. This handler immediately returns a taskId without waiting for the actual image generation, enabling non-blocking client interactions.
The apimartClient wrapper located in src/apimartClient.js automatically injects the Supabase JWT access token into request headers. This client library manages the communication between the front-end and the generation service while persisting task metadata to local storage under the key gpt-image-2-generated-tests:v1.
Behind the scenes, api/_lib/generation.js validates incoming parameters and creates a record in the Supabase generation_tasks table, as defined in supabase/migrations/20260828090000_apimart_generation_tasks.sql. A background worker then processes the queue, calling the OpenAI /v1/images/generations endpoint and updating the task status upon completion.
Integration Patterns
Direct POST Pattern
The simplest integration involves calling POST /api/generate-image directly with a JSON payload containing prompt, style, width, and height parameters. The server responds immediately with a taskId while processing continues asynchronously.
This pattern suits single-page React applications and simple web forms that do not require real-time progress updates. The client receives confirmation that the request entered the queue without maintaining a persistent connection.
Polling Pattern
For clients that need progress visibility without server-push capabilities, the system supports status polling via GET /api/generation/status?taskId={id}. The endpoint queries the generation_tasks table and returns the current state: queued, processing, or done.
When the status transitions to done, the response includes the resultUrl pointing to the generated asset. This pattern appears in src/apimartClient.js where the library implements automatic retry logic with exponential backoff.
Webhook Callback Pattern
Applications requiring push-based notifications can provide a callbackUrl in the initial request payload. The api/generation/callback.js handler executes when the background worker completes generation, issuing a POST request to the specified endpoint with the taskId, resultUrl, and final status.
This pattern eliminates the need for continuous polling and reduces server load for mobile applications or third-party service integrations that prefer event-driven architectures.
Batch Generation Pattern
The API supports submitting multiple prompts in a single request by passing an array of generation objects. The server creates individual task records for each prompt and returns an array of taskId values, enabling bulk content creation workflows for newsletters or gallery applications.
The implementation reuses the validation logic in api/_lib/generation.js but wraps the creation calls in a transaction to ensure atomicity across the batch.
Authenticated Client Library Pattern
The apimartClient class exported from src/apimartClient.js provides the most robust integration method. This wrapper automatically handles Supabase authentication, request retries, error normalization, and local caching of task history.
The library stores recent task IDs in browser local storage, allowing applications to resume and display previous generations after page refreshes without re-querying the database.
Security and State Management
Every endpoint requires a valid Supabase JWT obtained from supabaseClient.js and passed in the Authorization: Bearer header. The server validates this token before permitting access to the generation pipeline.
The generation_tasks table schema persists task metadata including creation timestamps, user associations, and result URLs. This persistence layer ensures that long-running generation jobs survive server restarts and allow users to retrieve historical results.
Client-side state management uses the constant GENERATED_TESTS_STORAGE_KEY to cache task IDs, providing offline awareness of pending generations and enabling optimistic UI updates while the background worker processes the queue.
Implementation Examples
Basic React Integration
import { generateImage } from './apimartClient';
const payload = {
prompt: 'A futuristic city at sunrise, hyper-realistic',
style: 'photorealistic',
width: 1024,
height: 1024,
};
const { taskId } = await generateImage(payload);
let status = 'queued';
while (status !== 'done') {
const res = await fetch(`/api/generation/status?taskId=${taskId}`);
const data = await res.json();
status = data.status;
if (status === 'done') {
console.log('Image ready:', data.resultUrl);
} else {
await new Promise(r => setTimeout(r, 2000));
}
}
Direct API Access with cURL
curl -X POST https://your-domain.com/api/generate-image \
-H "Authorization: Bearer <SUPABASE_JWT>" \
-H "Content-Type: application/json" \
-d '{
"prompt":"A cute cat astronaut",
"style":"illustration",
"width":512,
"height":512,
"callbackUrl":"https://my-service.com/webhook"
}'
Response:
{
"taskId": "c1f3a9e1-7b2d-4e5a-9d9f-2d5b6f8a9c7b"
}
Webhook Consumer Implementation
app.post('/webhook', async (req, res) => {
const { taskId, resultUrl, status } = req.body;
if (status === 'done') {
console.log(`Task ${taskId} finished – image at ${resultUrl}`);
}
res.sendStatus(200);
});
Summary
- Entry Point:
api/generate-image.jsaccepts authenticated POST requests and returns immediate task IDs - Async Monitoring: Use
GET /api/generation/statusfor polling or providecallbackUrlfor webhook notifications viaapi/generation/callback.js - Client SDK:
src/apimartClient.jshandles JWT injection, retries, and local storage caching undergpt-image-2-generated-tests:v1 - Persistence: All tasks stored in the Supabase
generation_taskstable defined in the migration file20260828090000_apimart_generation_tasks.sql - Scalability: Background workers process the queue independently from the HTTP request/response cycle
Frequently Asked Questions
How does authentication work for GPT-Image2 API requests?
The system uses Supabase JWT tokens that must be included in the Authorization: Bearer header of every request. The apimartClient automatically retrieves the current session token from Supabase and attaches it to outgoing calls, while the server validates the token before processing generation requests.
What is the difference between polling and webhook patterns?
Polling requires the client to repeatedly call GET /api/generation/status to check if the status field changed from queued or processing to done. The webhook pattern allows clients to specify a callbackUrl in the initial request, causing api/generation/callback.js to push the result to their endpoint when generation completes, eliminating the need for continuous status checks.
Can I generate multiple images in a single API call?
Yes, the API supports batch generation by sending an array of prompt objects to POST /api/generate-image. The server creates individual task records for each prompt and returns an array of taskId values, enabling efficient bulk processing while maintaining the same asynchronous workflow as single-image requests.
Where are generation tasks stored if the server restarts?
Tasks persist in the Supabase generation_tasks table, defined in supabase/migrations/20260828090000_apimart_generation_tasks.sql. This database layer ensures that queued and processing jobs survive server restarts, and clients can retrieve historical results using the original taskId even after the generation worker recovers from interruption.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →