# How to Detect Terminal Task Statuses in GPT-Image2

> Learn how to detect terminal task statuses for GPT-Image2. Discover how to poll the /api/generation/status endpoint to check if a generation is completed or failed.

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

---

**GPT-Image2 considers a generation task terminal when the provider reports either `completed` or `failed`, enabling clients to determine completion by polling the `/api/generation/status` endpoint and inspecting the `status` field in the JSON response.**

The `freestylefly/awesome-gpt-image-2` repository implements a robust task lifecycle for image generation workflows. Detecting terminal task statuses is essential for managing UI states, releasing resources, and displaying final results or errors to users. This article examines the detection logic implemented in the API layer and provides practical code for checking task completion.

## What Constitutes a Terminal Status

In GPT-Image2, a task reaches a terminal state when no further processing will occur. The system recognizes two terminal values:

- **`completed`** – The image generation succeeded and a result URL is available.
- **`failed`** – The generation encountered an error and the task cannot proceed.

These values are normalized from the provider’s native terminology and exposed through the public API, ensuring consistent client behavior regardless of upstream changes.

## Server-Side Detection in [`api/generation/status.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/generation/status.js)

The primary detection logic resides in [`api/generation/status.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/generation/status.js), which handles `GET` requests to `/api/generation/status`. The endpoint accepts a `taskId` query parameter and determines whether the task has finished by examining the `status` property.

### The Terminal State Check

After retrieving the task—either from a stored reservation or by calling the APIMart API via `getApimartTask`—the handler evaluates the status field:

```js
if (['completed', 'failed'].includes(task.status)) {
  await settlePlatformGeneration(auth.client, reservation, task);
}

```

This check appears at lines 63–66 in [`api/generation/status.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/generation/status.js). When the condition evaluates to true, the system finalizes the task by invoking `settlePlatformGeneration`, which persists the result or error and updates the reservation record.

### Handling Completed vs. Failed States

- **Completed tasks**: The `settlePlatformGeneration` function stores the result image URL and marks the reservation as finalized.
- **Failed tasks**: The system releases the reservation and records an error code, preventing resource leaks while maintaining audit trails.

## Normalizing Provider Status Values

The backend must reconcile differences between the provider’s status vocabulary and the public API contract. The provider uses `succeeded` to indicate a finished generation, while the API exposes `completed`.

The `formatStoredGeneration` utility in [`api/_lib/generation.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/generation.js) handles this translation:

- Maps `succeeded` → `completed`
- Sets progress to `100%` for terminal successes
- Ensures the response shape matches expectations defined in [`api/_lib/generation.test.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/generation.test.js)

This normalization guarantees that clients only need to check for the standardized `completed` value, not provider-specific variants.

## Client-Side Implementation

To detect terminal statuses from the browser or another HTTP client, poll the status endpoint and examine the `status` property. A value of `completed` or `failed` indicates the task is finished.

```js
// Query the status of a generation task
async function getTaskStatus(taskId) {
  const resp = await fetch(`/api/generation/status?taskId=${taskId}`);
  const data = await resp.json();

  if (!data.ok) {
    throw new Error(`Error ${data.error}`);
  }

  // Terminal when status is "completed" or "failed"
  const isTerminal = ['completed', 'failed'].includes(data.status);
  console.log('Task status:', data.status, 'Terminal?', isTerminal);
  return { ...data, isTerminal };
}

// Usage
getTaskStatus('task_abcdefgh')
  .then(info => {
    if (info.isTerminal) {
      console.log('Result image:', info.image);
    } else {
      console.log('Task still in progress…');
    }
  })
  .catch(err => console.error(err));

```

When the task is terminal, the response includes the `image` URL, `cost`, and `expiresAt` timestamp. For non-terminal tasks, these fields are omitted to reduce payload size.

## Key Components in the Detection Flow

Understanding the full architecture requires familiarity with these modules:

- **[`api/generation/status.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/generation/status.js)** – The public endpoint handler that detects terminal states and triggers settlement logic.
- **[`api/_lib/generation.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/generation.js)** – Core utilities including `formatStoredGeneration` for status normalization and `settlePlatformGeneration` for finalizing reservations.
- **[`api/_lib/generation.test.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/generation.test.js)** – Validates that stored terminal rows are correctly transformed into the unified browser-facing shape.
- **[`shared/apimart.test.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/shared/apimart.test.js)** – Confirms that HTTP errors and terminal task failures map to distinct, user-facing error codes.

## Summary

- **Terminal values**: GPT-Image2 treats `completed` and `failed` as the only terminal statuses.
- **Detection mechanism**: Check `task.status` in the response from `/api/generation/status`.
- **Normalization**: The backend converts the provider’s `succeeded` status to `completed` via `formatStoredGeneration`.
- **Settlement**: Terminal tasks trigger `settlePlatformGeneration` to persist results and release reservations.
- **Polling strategy**: Clients should poll the endpoint (which sets `Cache-Control: no-store`) until `isTerminal` is true.

## Frequently Asked Questions

### What HTTP endpoint should I use to check if a GPT-Image2 task is finished?

Send a `GET` request to `/api/generation/status?taskId={taskId}`. The endpoint returns a JSON object where the `status` field indicates the current state. When this value is either `completed` or `failed`, the task has reached a terminal state and will no longer change.

### Why does the API return "completed" when the provider reports "succeeded"?

The backend normalizes provider-specific terminology through `formatStoredGeneration` in [`api/_lib/generation.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/generation.js). The upstream provider uses `succeeded` for successful generations, but the public API unifies this to `completed` for consistency across client implementations, also setting progress to `100%` in the response.

### How does the system handle failed terminal tasks?

When the `status` is `failed`, the `settlePlatformGeneration` function in [`api/_lib/generation.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/api/_lib/generation.js) releases the reservation to free up resources and records the specific error code. This ensures that failed tasks do not consume capacity indefinitely while preserving diagnostic information for debugging.

### Can I cache the status endpoint response to reduce API calls?

No. The endpoint explicitly sets `Cache-Control: no-store` headers via the internal `json` helper function to prevent caching of intermediate states. This guarantees that polling clients always receive the current task status rather than a stale, non-terminal response.