# How APIMart Handles Image Generation Tasks in awesome-gpt-image-2

> Discover how APIMart handles image generation in awesome-gpt-image-2. Learn about its three-layer architecture for efficient task orchestration and client-server communication.

- Repository: [苍何/awesome-gpt-image-2](https://github.com/freestylefly/awesome-gpt-image-2)
- Tags: how-to-guide
- Published: 2026-09-10

---

**APIMart serves as the backend provider for image generation in awesome-gpt-image-2, orchestrating tasks through a three-layer architecture that separates shared utilities, server-side API handling, and client-side task management.**

The awesome-gpt-image-2 repository by freestylefly integrates APIMart to power GPT-image-2 model generation through a robust TypeScript/JavaScript implementation. This architecture enables both platform-mediated and direct personal API key workflows while handling task lifecycle management, caching, and comprehensive error translation.

## Three-Layer Architecture

The integration divides responsibilities across shared helpers, server middleware, and browser clients to ensure consistent behavior across environments.

### Shared Utilities Layer

The foundation resides in [`shared/apimart.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/shared/apimart.js), which exports pure functions usable in both Node.js and browser contexts. This module defines constants, payload builders, response normalizers, and pricing utilities that remain agnostic to the execution environment.

### Server-Side API Layer

Located in [`api/_lib/apimart.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/apimart.js) and consumed by [`api/generate-image.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/generate-image.js), this layer manages secure communication with APIMart. It reads the `APIMART_API_KEY` environment variable, submits generation requests to `https://api.apimart.ai/v1/images/generations`, and stores task IDs in Supabase. The server returns **202 Accepted** responses to clients and translates upstream errors into semantic public codes like `UPSTREAM_BUSY` or `SERVER_NOT_CONFIGURED`.

### Client-Side Wrapper

The browser implementation in [`src/apimartClient.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/src/apimartClient.js) offers dual operation modes: **personal key** (direct APIMart calls) and **platform key** (proxied through the server API). It persists API keys and task states in `localStorage` using keys `gpt-image-2-apimart-key:v1`, `gpt-image-2-pending-tests:v1`, and `gpt-image-2-generated-tests:v1`.

## The Generation Workflow

Understanding how APIMart handles image generation tasks requires examining the request lifecycle from submission to completion.

### Configuration and Initialization

The server determines APIMart availability through `getApimartConfig()` in [`api/_lib/apimart.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/apimart.js), which checks for the presence of `process.env.APIMART_API_KEY`. This boolean flag dictates whether the provider appears as "configured" in health checks.

### Submitting Generation Tasks

**Platform Mode (Server-Proxied):**

1. The client POSTs to `/api/generate-image` with a payload containing `caseId`, `prompt`, and `language`.
2. The handler validates the prompt and reserves a usage slot in Supabase.
3. It invokes `submitApimartGeneration()`, which calls `buildApimartGenerationPayload()` to construct the request body.
4. The function POSTs to APIMart's `/v1/images/generations` endpoint.
5. `extractApimartTaskId()` normalizes the response, extracting the task identifier for storage in the `generation_reservations` table.

**Personal Mode (Direct Browser):**

Users with their own APIMart credentials bypass the server entirely. The `submitPersonalGeneration(prompt, apiKey, language)` function in [`src/apimartClient.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/src/apimartClient.js) constructs and submits the identical payload directly from the browser to the APIMart API.

### Task Status Polling

Both modes utilize `normalizeApimartTask()` to convert APIMart's response format into a unified shape: `{ taskId, status, progress, image, expiresAt, cost, ... }`.

- **Platform polling** uses `fetchPlatformTask(taskId, accessToken, language)`, which queries `/api/generation/status` and internally forwards to `getApimartTask()`.
- **Personal polling** uses `fetchPersonalTask(taskId, apiKey, language)` to call `GET https://api.apimart.ai/v1/tasks/<taskId>` directly.

The `pollApimartTask(fetchTask, options)` utility manages the polling lifecycle, repeatedly invoking the fetch function until `isTerminalApimartStatus(status)` returns true (indicating `completed` or `failed` status). It respects `Retry-After` headers when encountering `APIMART_RATE_LIMITED` errors and supports cancellation via `AbortSignal`.

## Error Handling and Rate Limiting

The implementation provides granular error translation through the `apimartErrorCode()` helper, which maps HTTP status codes to specific semantic identifiers:

- `APIMART_API_KEY_INVALID` for authentication failures
- `APIMART_BALANCE_REQUIRED` for insufficient credits
- `APIMART_RATE_LIMITED` for throttling scenarios

Server-side errors are wrapped with `upstreamError()`, while client-side errors use `responseError()`. The `publicErrorCode()` function further maps these internal codes to public-facing messages suitable for API consumers, translating to appropriate HTTP status codes such as `503` for upstream busy states or `500` for internal failures.

## Practical Implementation Examples

### Submitting a Generation via Platform API

```javascript
// POST /api/generate-image
await fetch('/api/generate-image', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ 
    caseId: 123, 
    prompt: 'A cyberpunk city at sunrise', 
    language: 'en' 
  })
});

```

The server handler in [`api/generate-image.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/generate-image.js) processes this request and internally calls `submitApimartGeneration()` (defined at line 44 in [`api/_lib/apimart.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/apimart.js)) to communicate with APIMart.

### Direct Generation with Personal API Key

```javascript
import { submitPersonalGeneration, getStoredApimartKey } from './apimartClient.js';

const apiKey = getStoredApimartKey();  // reads from localStorage
const result = await submitPersonalGeneration(
  'A futuristic robot painting', 
  apiKey, 
  'en'
);
// result => { taskId: 'task_abc123…', status: 'submitted' }

```

### Polling for Task Completion

```javascript
import { pollApimartTask, fetchPersonalTask } from './apimartClient.js';

const apiKey = getStoredApimartKey();
const taskId = 'task_…';

await pollApimartTask(
  () => fetchPersonalTask(taskId, apiKey, 'en'),
  {
    onProgress: t => console.log('Progress', t.progress),
    maxAttempts: 100,
    intervalMs: 2000
  }
);
// Returns normalized task object when status becomes 'completed' or 'failed'

```

### Retrieving Cached Results

```javascript
import { getSavedGeneration } from './apimartClient.js';

const saved = getSavedGeneration(123); // caseId = 123
if (saved) {
  console.log('Cached image URL:', saved.image);
}

```

### Server-Side Error Translation

```javascript
import { publicErrorCode, publicErrorStatus } from './api/generate-image.js';

try {
  // ... generation logic
} catch (err) {
  const code = publicErrorCode(err);
  const status = publicErrorStatus(code);
  res.status(status).json({ ok: false, error: code });
}

```

## Summary

- **APIMart integration** in awesome-gpt-image-2 uses a three-tier architecture separating shared utilities ([`shared/apimart.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/shared/apimart.js)), server handlers ([`api/_lib/apimart.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/apimart.js), [`api/generate-image.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/generate-image.js)), and browser clients ([`src/apimartClient.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/src/apimartClient.js)).
- **Dual operation modes** support both platform-mediated requests (using server-stored API keys) and personal key workflows (direct browser-to-APIMart communication).
- **Task lifecycle management** includes submission via `submitApimartGeneration()` or `submitPersonalGeneration()`, polling through `pollApimartTask()`, and normalization via `normalizeApimartTask()`.
- **Robust error handling** maps upstream APIMart errors to semantic codes like `APIMART_RATE_LIMITED` and `APIMART_API_KEY_INVALID`, with appropriate HTTP status code translation for API consumers.
- **Local persistence** stores API keys and generation history in `localStorage` using version-prefixed keys to maintain state across sessions.

## Frequently Asked Questions

### What environment variables are required to configure APIMart in awesome-gpt-image-2?

The server-side integration requires `APIMART_API_KEY` to be set in the environment. The `getApimartConfig()` function in [`api/_lib/apimart.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/apimart.js) checks for this variable to determine if the provider is properly configured before attempting any upstream requests.

### How does the system handle APIMart rate limits?

When APIMart returns rate limit errors, the client detects `APIMART_RATE_LIMITED` codes and respects the `Retry-After` header. The `pollApimartTask()` utility automatically implements backoff strategies, while the server translates these into `503` status codes with appropriate retry guidance for API consumers.

### Can users use their own APIMart API keys instead of the platform's?

Yes. The [`src/apimartClient.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/src/apimartClient.js) module supports a personal key mode through `submitPersonalGeneration()` and `fetchPersonalTask()`, allowing users to store their API key in `localStorage` (under `gpt-image-2-apimart-key:v1`) and make direct requests to `https://api.apimart.ai/v1/images/generations` without routing through the platform's server infrastructure.

### Where are generation tasks stored during processing?

Platform-generated tasks are persisted in Supabase within the `generation_reservations` table, allowing the system to track usage and task states across distributed workers. Client-side tasks and results are cached in `localStorage` using keys `gpt-image-2-pending-tests:v1` and `gpt-image-2-generated-tests:v1` for immediate retrieval without repeated API calls.