EggAPI/docs / async-tasks
sign in

Async Tasks

Create, poll, list, and receive callbacks for EggAPI generation tasks

Every EggAPI generation model is asynchronous. POST /v1/generate creates the task immediately and returns 202 Accepted; workers process it in the background, and you read the result by polling or through a webhook.

Lifecycle

  1. Your app calls POST /v1/generate; the API returns 202 Accepted with the task ID.
  2. A worker starts the generation with the upstream provider and polls it until it finishes.
  3. The worker saves the output, usage, and cost on the task.
  4. Your app reads the task with GET /v1/tasks/{id} and gets it back as completed or failed.

Task statuses:

StatusMeaning
pendingTask was created and queued.
processingWorker started provider execution or polling.
completedOutput, cost, and usage have been recorded.
failedThe task ended with an error message.

Create a Task

bash
curl -X POST https://api.eggapi.ai/v1/generate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-image-2/text-to-image",
    "prompt": "A dashboard hero image with glass UI panels",
    "aspect_ratio": "16:9",
    "resolution": "1k",
    "num_outputs": 1
  }'

Response:

json
{
  "data": {
    "id": "gen_3f2a9c1d-7b4",
    "status": "pending",
    "model": "openai/gpt-image-2/text-to-image",
    "type": "image_generate",
    "cost": "$0.00",
    "created_at": "2026-05-08T10:30:00Z"
  },
  "error": null
}

Poll a Task

bash
curl https://api.eggapi.ai/v1/tasks/gen_3f2a9c1d-7b4 \
  -H "Authorization: Bearer YOUR_API_KEY"

Completed image task:

json
{
  "data": {
    "id": "gen_3f2a9c1d-7b4",
    "status": "completed",
    "model": "openai/gpt-image-2/text-to-image",
    "type": "image_generate",
    "output": {
      "url": "https://file.eggapi.ai/images/gen_3f2a9c1d-7b4/0.png",
      "urls": ["https://file.eggapi.ai/images/gen_3f2a9c1d-7b4/0.png"]
    },
    "cost": "$0.0096",
    "created_at": "2026-05-08T10:30:00Z",
    "started_at": "2026-05-08T10:30:01Z",
    "completed_at": "2026-05-08T10:30:10Z"
  },
  "error": null
}

List Tasks

bash
curl "https://api.eggapi.ai/v1/tasks?page=1&per_page=20" \
  -H "Authorization: Bearer YOUR_API_KEY"

The list is under data.items, newest first, and pagination fields are under data.pagination (page, per_page, total, total_pages). per_page defaults to 20 and is at most 100.

Webhooks

Pass webhook_url when creating a task:

json
{
  "model": "google/nano-banana-2/text-to-image",
  "prompt": "A studio portrait with soft lighting",
  "webhook_url": "https://example.com/eggapi/webhook"
}

EggAPI posts JSON to your URL after completion or failure. All models use the same webhook envelope; different result types only change type and the optional fields under output. It sends these headers:

HeaderDescription
X-EggAPI-TimestampUnix timestamp used in the signature payload.
X-EggAPI-Signaturesha256= plus HMAC-SHA256 of {timestamp}.{raw_body} using your webhook secret.

Common fields:

FieldDescription
eventtask.completed or task.failed.
task_idEggAPI task ID, matching data.id from the polling API.
statuscompleted or failed.
modelModel ID from the original request.
typeTask type: image_generate, image_edit, or video_generate.
outputPresent on success. Depending on the task type, it may include url, urls, duration_seconds, width, and height.
errorPresent on failure.
costTask cost in USD as a decimal string.
timestampUnix timestamp when the webhook payload was generated.

Completed image payload:

json
{
  "event": "task.completed",
  "task_id": "gen_3f2a9c1d-7b4",
  "status": "completed",
  "model": "google/nano-banana-2/text-to-image",
  "type": "image_generate",
  "output": {
    "url": "https://file.eggapi.ai/images/gen_3f2a9c1d-7b4/0.png",
    "urls": ["https://file.eggapi.ai/images/gen_3f2a9c1d-7b4/0.png"],
    "width": 1024,
    "height": 576
  },
  "cost": "0.013500",
  "timestamp": 1778217000
}

Completed video payload:

json
{
  "event": "task.completed",
  "task_id": "gen_8c41e07a-2d9",
  "status": "completed",
  "model": "bytedance/seedance-2.5/text-to-video",
  "type": "video_generate",
  "output": {
    "url": "https://file.eggapi.ai/videos/gen_8c41e07a-2d9/output.mp4",
    "urls": ["https://file.eggapi.ai/videos/gen_8c41e07a-2d9/output.mp4"],
    "duration_seconds": 5
  },
  "cost": "1.252275",
  "timestamp": 1778217000
}

Failed payload:

json
{
  "event": "task.failed",
  "task_id": "gen_3f2a9c1d-7b4",
  "status": "failed",
  "model": "google/nano-banana-2/text-to-image",
  "type": "image_generate",
  "error": "generation failed: upstream provider unavailable",
  "cost": "0.000000",
  "timestamp": 1778217000
}

Webhook delivery uses a 30 second HTTP timeout. A delivery that fails or returns a non-2xx status is retried up to 5 attempts, starting 30 seconds later and doubling each time.

Verify the Signature

Find your webhook secret in the dashboard, then compare signatures over the raw request body before parsing it:

javascript
import crypto from "node:crypto";

function verifyEggApiWebhook(rawBody, timestamp, signature, secret) {
  const expected = "sha256=" + crypto
    .createHmac("sha256", secret)
    .update(`${timestamp}.${rawBody}`)
    .digest("hex");
  return signature.length === expected.length
    && crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
}

Reject requests whose X-EggAPI-Timestamp is far from the current time to prevent replays.

Polling Helper

javascript
async function waitForTask(taskId, apiKey, timeoutMs = 300000) {
  const start = Date.now();

  while (Date.now() - start < timeoutMs) {
    const response = await fetch(`https://api.eggapi.ai/v1/tasks/${taskId}`, {
      headers: { "Authorization": `Bearer ${apiKey}` }
    });
    const { data, error } = await response.json();

    if (error) throw new Error(error.message);
    if (data.status === "completed") return data;
    if (data.status === "failed") throw new Error(data.error || "Task failed");

    await new Promise((resolve) => setTimeout(resolve, 3000));
  }

  throw new Error("Task timed out");
}
connected
mcp https://api.eggapi.ai/mcp
models ...
Claude Code · Codex · MCP
█