How the GPT-Image2 Reservation System Works for Image Generation
The GPT-Image2 reservation system creates a unique database slot for every image generation request, ensuring idempotent processing by tracking the request from pending through completion or failure via Supabase reservations and provider callbacks.
The freestylefly/awesome-gpt-image-2 repository implements a robust reservation system for GPT-Image2 image generation that guarantees reliable task tracking and prevents duplicate processing. This architecture uses Supabase as the persistence layer and implements a state machine that transitions reservations from pending to succeeded or failed based on external provider responses.
Creating a Generation Reservation
When a client initiates image generation via POST /api/generate-image, the handler defined in api/generate-image.js immediately inserts a row into the Supabase table generation_reservations. This record establishes a unique slot with status = 'pending' and provider = 'apimart', returning a reservation_id to the caller before any external processing begins.
If the database insertion fails, the handler throws RESERVATION_FAILED, ensuring the client receives an immediate error rather than a lost request:
// src: api/generate-image.js (lines 27-48)
const reservation = normalizeReservation(data);
if (!reservation) throw new Error('RESERVATION_FAILED');
return reservation;
Reserving the Task with Metadata
The internal helper reserveGeneration (called from api/generate-image.js) persists the reservation ID alongside metadata required for the provider. This reservation ID serves as the correlation key that later matches the provider's asynchronous callback to the original client request, ensuring every generation task maintains a persistent identity throughout its lifecycle.
Handling Provider Callbacks
When the external provider (Apimart) completes image rendering, it POSTs to /api/generation/callback. The handler in api/generation/callback.js uses findReservation to locate the pending record and validates its state before proceeding:
// src: api/generation/callback.js (lines 29-38)
const reservation = await findReservation(client, taskId);
if (!reservation) return { state: 'ignored' };
if (reservation.status !== 'pending') return { state: 'duplicate' };
await settle(client, reservation, verifiedTask);
This validation prevents processing duplicate callbacks or updating already-settled reservations.
Settlement Logic and State Transitions
The core settlement logic resides in settlePlatformGeneration within api/_lib/generation.js. This function updates the reservation with provider result fields (provider_cost_usd, provider_result_url) and executes database RPC calls to finalize the state:
- Successful completion: Calls
complete_generation_reservationto mark the reservation assucceeded - Failure handling: Calls
release_generation_reservationwith an error code to transition tofailed
// src: api/_lib/generation.js (lines 60-84)
if (task.status === 'completed' && task.image) {
await client.rpc('complete_generation_reservation', { p_reservation_id: reservation.id });
} else {
await client.rpc('release_generation_reservation', {
p_reservation_id: reservation.id,
p_error_code: task.errorCode || 'GENERATION_FAILED'
});
}
Querying Generation Status
Clients poll GET /api/generation/status/:taskId to retrieve results. The handler uses findPlatformGeneration to fetch the reservation from Supabase, then formats a public-safe response using formatStoredGeneration:
// src: api/_lib/generation.js (lines 29-45)
export function formatStoredGeneration(reservation) {
if (!reservation) return null;
const succeeded = reservation.status === 'succeeded';
const failed = reservation.status === 'failed';
if (!succeeded && !failed) return null;
return {
taskId: reservation.provider_task_id,
status: succeeded ? 'completed' : 'failed',
image: reservation.provider_result_url || '',
// …
};
}
Idempotency and Error Handling
The system guarantees exactly-once semantics through multiple defensive mechanisms:
- Pending-state validation:
settlePlatformGenerationverifies the reservation status remainspendingbefore updating, preventing race conditions during concurrent callback processing - Idempotent release: The
release_generation_reservationRPC is designed to be idempotent, ensuring failed tasks release the reservation exactly once regardless of retry attempts - Duplicate detection: The callback handler returns
{ state: 'duplicate' }when encountering reservations already processed
Complete Client Implementation Example
Below is a complete client-side implementation demonstrating reservation creation, polling, and result retrieval:
// 1️⃣ Request a new image (client side)
fetch('/api/generate-image', {
method: 'POST',
body: JSON.stringify({ prompt: 'a futuristic city at sunset' })
})
.then(r => r.json())
.then(({ reservationId }) => {
console.log('Reservation created:', reservationId);
// 2️⃣ Poll for status
const poll = setInterval(() => {
fetch(`/api/generation/status/${reservationId}`)
.then(r => r.json())
.then(data => {
if (data.status === 'completed') {
clearInterval(poll);
console.log('Image ready:', data.image);
} else if (data.status === 'failed') {
clearInterval(poll);
console.error('Generation failed:', data.errorMessage);
}
});
}, 3000);
});
Summary
- Unique slot guarantee: Every
POST /api/generate-imagecreates a distinct row ingeneration_reservationswithstatus = 'pending'before external processing begins - State machine tracking: Reservations transition through
pending→succeeded/failedviacomplete_generation_reservationorrelease_generation_reservationRPC calls - Safe callback handling: The
api/generation/callback.jshandler validates reservation state before callingsettlePlatformGenerationto prevent duplicate processing - Idempotent settlement: Core functions in
api/_lib/generation.jsensure exactly-once execution regardless of provider retry behavior - Clean API surface: Clients interact via standard REST endpoints while internal implementation details remain encapsulated in library functions
Frequently Asked Questions
What happens if the provider callback fails or times out?
The reservation remains in pending status indefinitely until a successful callback occurs or manual intervention occurs. Clients should implement polling timeouts at the application level, as the GET /api/generation/status/:taskId endpoint (implemented in api/generation/status.js) only returns results once the reservation reaches a terminal state via formatStoredGeneration.
How does the system prevent duplicate image generation charges?
The settlePlatformGeneration function in api/_lib/generation.js checks that the reservation status is strictly pending before invoking complete_generation_reservation. If a duplicate callback arrives after settlement, the handler in api/generation/callback.js returns { state: 'duplicate' } and ignores the payload, ensuring providers cannot bill for the same reservation twice.
What database tables does the reservation system use?
The system primarily uses the generation_reservations table in Supabase, which stores fields including reservation_id, provider_task_id, status, provider, provider_cost_usd, and provider_result_url. State transitions occur through RPC functions complete_generation_reservation and release_generation_reservation rather than direct table updates.
Can I use a different provider instead of Apimart?
While the current implementation in api/generate-image.js hardcodes provider = 'apimart', the architecture supports provider abstraction. The provider field in the reservation record and the callback handler's use of provider_task_id allow for future extension, though you would need to modify the provider-specific logic in api/generate-image.js and the callback verification in api/generation/callback.js to integrate alternative services.
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 →