# How to Handle Rate Limiting When Using APIMart: A Complete Guide

> Learn how to handle APIMart rate limiting errors with our complete guide. Discover how the SDK translates 429 responses and uses retryAfterMs for automatic retries.

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

---

**When APIMart returns HTTP 429, the SDK translates it into a `APIMART_RATE_LIMITED` error that includes a `retryAfterMs` property, allowing you to pause and retry automatically.**

The **freestylefly/awesome-gpt-image-2** repository provides a robust JavaScript SDK for image generation through APIMart. Learning to handle rate limiting when using APIMart ensures your application remains responsive and avoids service disruptions when you hit per-key request quotas.

## Understanding APIMart Rate Limits

APIMart enforces strict per-key request quotas to ensure fair usage across all clients. When you exceed your allocated limit, the API responds with **HTTP 429** (Too Many Requests). The SDK in this repository transforms these responses into structured errors that contain actionable retry information.

### Detecting Rate Limit Errors

The SDK identifies rate-limit conditions through the `apimartErrorCode` utility found in [`shared/apimart.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/shared/apimart.js). At line 73, this function maps HTTP 429 responses to the constant `APIMART_RATE_LIMITED`, creating a standardized error object you can catch reliably.

```javascript
// Error detection happens automatically
if (error.code === 'APIMART_RATE_LIMITED') {
  console.log('Rate limit exceeded');
}

```

### Reading the Retry-After Interval

Every rate-limit response includes a `Retry-After` header indicating how long to wait before retrying. The `retryAfterMilliseconds` helper (lines 81–90 in [`shared/apimart.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/shared/apimart.js)) parses this header—whether it contains seconds or a timestamp—and attaches the value to `error.retryAfterMs` as a millisecond integer.

```javascript
// The error object includes the wait time
const waitTime = error.retryAfterMs || 2000; // fallback to 2 seconds

```

## Automatic Retry Mechanisms in the SDK

The repository implements intelligent back-off logic directly in the polling utilities, reducing the boilerplate required in your application code.

### The pollApimartTask Function

The `pollApimartTask` function in [`src/apimartClient.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/src/apimartClient.js) (lines 44–46) automatically catches `APIMART_RATE_LIMITED` errors during status polling. When this occurs, the function pauses execution for the duration specified in `error.retryAfterMs` before attempting the next poll, ensuring you never exceed the API's suggested retry rate.

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

async function waitForCompletion(taskId, apiKey) {
  const fetchTask = () => fetchPersonalTask(taskId, apiKey, 'en');
  
  // Automatically handles 429 errors with proper delays
  const result = await pollApimartTask(fetchTask, {
    intervalMs: 3000,
    maxAttempts: 120
  });
  
  return result;
}

```

## Implementing Rate Limit Handling

While the SDK handles polling retries automatically, generation submissions and other direct API calls require explicit error handling in your application layer.

### Basic Error Handling Pattern

Wrap your submission calls in try-catch blocks that specifically check for `APIMART_RATE_LIMITED`. Use the `retryAfterMs` property to delay your retry attempt.

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

async function generateImage(prompt, apiKey) {
  try {
    await verifyPersonalApimartKey(apiKey);
    const { taskId } = await submitPersonalGeneration(prompt, apiKey, 'en');
    return taskId;
  } catch (err) {
    if (err.code === 'APIMART_RATE_LIMITED') {
      console.warn(`Rate limited. Retry after ${err.retryAfterMs}ms`);
      await new Promise(res => setTimeout(res, err.retryAfterMs));
      return generateImage(prompt, apiKey); // Retry once
    }
    throw err;
  }
}

```

### Exponential Backoff for Batch Processing

When submitting multiple generations in sequence, implement exponential backoff to prevent hammering the API. Start with a base delay and double the wait time after each consecutive rate-limit error, capping at 60 seconds.

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

async function submitWithBackoff(prompt, apiKey) {
  let backoff = 2000; // 2 seconds initial
  
  for (let attempt = 0; attempt < 5; attempt++) {
    try {
      return await submitPersonalGeneration(prompt, apiKey, 'en');
    } catch (e) {
      if (e.code !== 'APIMART_RATE_LIMITED') throw e;
      
      const waitMs = e.retryAfterMs || backoff;
      console.log(`Attempt ${attempt + 1} rate limited. Waiting ${waitMs}ms`);
      
      await new Promise(r => setTimeout(r, waitMs));
      backoff = Math.min(60000, backoff * 2); // Cap at 60 seconds
    }
  }
  throw new Error('Max retries exceeded due to rate limiting');
}

```

## Best Practices for Production Use

Follow these guidelines to maintain optimal performance when interacting with APIMart:

- **Respect `retryAfterMs`**: Never retry faster than the interval supplied by the API. The `pollApimartTask` implementation in [`src/apimartClient.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/src/apimartClient.js) already adheres to this constraint.
- **Secure API Key Storage**: The SDK stores keys under `APIMART_KEY_STORAGE_KEY`. Ensure this storage mechanism meets your application's security requirements.
- **Monitor Rate Limit Headers**: Although the SDK abstracts the `Retry-After` header, you can extend `fetchImpl` to log `X-RateLimit-Limit` and `X-RateLimit-Remaining` for capacity planning.
- **Graceful UI Feedback**: Surface user-friendly messages like "Please wait a moment before generating another image" when catching `APIMART_RATE_LIMITED` in frontend applications.
- **Abort Handling**: When users navigate away during polling, catch `APIMART_POLL_ABORTED` errors (lines 99–105 in [`src/apimartClient.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/src/apimartClient.js)) to clean up UI state properly.

## Summary

- APIMart returns **HTTP 429** when exceeding per-key quotas, which the SDK converts to `APIMART_RATE_LIMITED` errors via `apimartErrorCode` in [`shared/apimart.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/shared/apimart.js).
- The `retryAfterMilliseconds` function parses the `Retry-After` header and attaches the value to `error.retryAfterMs`.
- **Automatic handling**: `pollApimartTask` automatically pauses for the specified duration when encountering rate limits during polling loops.
- **Manual handling**: Wrap `submitPersonalGeneration` calls in try-catch blocks and implement exponential backoff starting at 2 seconds, capped at 60 seconds.
- Key files include [`shared/apimart.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/shared/apimart.js) for error utilities and [`src/apimartClient.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/src/apimartClient.js) for high-level API methods with built-in retry logic.

## Frequently Asked Questions

### What error code does APIMart return when I hit the rate limit?

When you exceed your request quota, APIMart returns HTTP 429. The SDK's `apimartErrorCode` function in [`shared/apimart.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/shared/apimart.js) translates this into the string `APIMART_RATE_LIMITED`, allowing you to detect rate limiting programmatically without checking status codes directly.

### How do I know how long to wait before retrying a failed request?

The SDK automatically parses the `Retry-After` response header using the `retryAfterMilliseconds` function (lines 81–90 in [`shared/apimart.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/shared/apimart.js)). This value is exposed as `error.retryAfterMs` on the thrown error object. If the header is missing, implement a fallback delay of 2000 milliseconds.

### Does the SDK handle retries automatically?

The `pollApimartTask` function in [`src/apimartClient.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/src/apimartClient.js) handles retries automatically for polling operations, pausing for `error.retryAfterMs` before continuing. However, submission functions like `submitPersonalGeneration` require you to implement your own retry logic using the error handling patterns shown in the examples above.

### Where is the API key stored in this library?

According to the source code in [`shared/apimart.js`](https://github.com/freestylefly/awesome-gpt-image-2/blob/main/shared/apimart.js), the SDK references `APIMART_KEY_STORAGE_KEY` for persistent storage of credentials. Ensure this storage location is secure and never expose the key in client-side logs or error messages.