{
  "openapi": "3.1.0",
  "info": {
    "title": "EggAPI",
    "description": "EggAPI public API: one API key for asynchronous image and video generation with Seedream, Nano Banana, GPT Image 2, Seedance, and Wan models.",
    "version": "1.0.0",
    "contact": {
      "email": "support@eggapi.ai"
    }
  },
  "servers": [
    {
      "url": "https://api.eggapi.ai",
      "description": "Production"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/v1/generate": {
      "post": {
        "operationId": "generate",
        "summary": "Create Generation Task",
        "description": "Create an asynchronous image or video generation task. Returns `202 Accepted` with a pending task; poll `GET /v1/tasks/{id}` or pass `webhook_url`. Image models bill per output image and video models bill per second, at the price of the requested resolution.",
        "tags": [
          "Generation"
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GenerateRequest"
              },
              "examples": {
                "text_to_image": {
                  "summary": "Text to image",
                  "value": {
                    "model": "google/nano-banana-2/text-to-image",
                    "prompt": "A clean editorial photo of a lemon tart on a steel table",
                    "aspect_ratio": "16:9",
                    "resolution": "1k",
                    "num_outputs": 1,
                    "webhook_url": "https://example.com/eggapi/webhook"
                  }
                },
                "image_edit": {
                  "summary": "Edit an image",
                  "value": {
                    "model": "google/nano-banana-pro/edit",
                    "prompt": "Replace the background with a quiet marble kitchen",
                    "image_urls": [
                      "https://file.eggapi.ai/uploads/image/your-user-id/input.png"
                    ],
                    "resolution": "2k"
                  }
                },
                "text_to_video": {
                  "summary": "Text to video",
                  "value": {
                    "model": "bytedance/seedance-2.5/text-to-video",
                    "prompt": "A black egg cracking open under soft studio light, slow push-in",
                    "duration": 5,
                    "resolution": "720p",
                    "aspect_ratio": "16:9",
                    "parameters": {
                      "generate_audio": true
                    }
                  }
                },
                "image_to_video": {
                  "summary": "Image to video",
                  "value": {
                    "model": "alibaba/wan-3.0/image-to-video",
                    "prompt": "The camera slowly orbits the product while light sweeps across it",
                    "image_urls": [
                      "https://file.eggapi.ai/uploads/image/your-user-id/first.png"
                    ],
                    "duration": 5,
                    "resolution": "1080p",
                    "parameters": {
                      "last_image": "https://file.eggapi.ai/uploads/image/your-user-id/last.png"
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Async task created",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskResponse"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden, or the balance cannot cover the estimated cost held when the task is created (INSUFFICIENT_BALANCE)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "429": {
            "description": "Rate limited",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "500": {
            "description": "Internal error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "NSFW filter unavailable (MODERATION_UNAVAILABLE)",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/uploads": {
      "post": {
        "operationId": "upload",
        "summary": "Upload Files",
        "tags": [
          "Uploads"
        ],
        "description": "Upload input images (up to 20 MB each), videos (200 MB) or audio (50 MB) and get public URLs to pass in image_urls or parameters. Up to 512 MB per request.",
        "requestBody": {
          "required": true,
          "content": {
            "multipart/form-data": {
              "schema": {
                "type": "object",
                "required": [
                  "files[]"
                ],
                "properties": {
                  "files[]": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "format": "binary"
                    },
                    "description": "One or more files. The field name files also works."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Files uploaded",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UploadResponse"
                }
              }
            }
          },
          "400": {
            "description": "Missing files, unsupported content type, or file too large",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "503": {
            "description": "File storage unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/tasks/{id}": {
      "get": {
        "operationId": "getTask",
        "summary": "Get Task",
        "description": "Retrieve the status and output of an asynchronous generation task.",
        "tags": [
          "Tasks"
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Task ID, for example `gen_abc123def456`.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Task details",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskResponse"
                }
              }
            }
          },
          "401": {
            "description": "Unauthorized",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          },
          "404": {
            "description": "Task not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ErrorResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/tasks": {
      "get": {
        "operationId": "listTasks",
        "summary": "List Tasks",
        "description": "Get a paginated list of your generation tasks.",
        "tags": [
          "Tasks"
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "description": "Items per page.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Task list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/TaskListResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/usage": {
      "get": {
        "operationId": "listUsage",
        "summary": "List Usage",
        "description": "Get a paginated list of your API usage records.",
        "tags": [
          "Usage"
        ],
        "parameters": [
          {
            "name": "page",
            "in": "query",
            "description": "Page number.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "default": 1
            }
          },
          {
            "name": "per_page",
            "in": "query",
            "description": "Items per page.",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 20
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Usage list",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageListResponse"
                }
              }
            }
          }
        }
      }
    },
    "/v1/usage/summary": {
      "get": {
        "operationId": "getUsageSummary",
        "summary": "Usage Summary",
        "description": "Get aggregated usage statistics grouped by model.",
        "tags": [
          "Usage"
        ],
        "responses": {
          "200": {
            "description": "Usage summary by model",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/UsageSummaryResponse"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "description": "EggAPI API key from the dashboard."
      }
    },
    "schemas": {
      "GenerateRequest": {
        "type": "object",
        "required": [
          "model",
          "prompt"
        ],
        "properties": {
          "model": {
            "type": "string",
            "description": "Published model ID. See https://eggapi.ai/docs/models for the current list.",
            "examples": [
              "bytedance/seedream-v5.0-pro",
              "bytedance/seedream-v5.0-pro/edit",
              "bytedance/seedream-v4.5",
              "bytedance/seedream-v4.5/edit",
              "google/nano-banana-pro/text-to-image",
              "google/nano-banana-pro/edit",
              "google/nano-banana-2/text-to-image",
              "google/nano-banana-2/edit",
              "openai/gpt-image-2/text-to-image",
              "openai/gpt-image-2/edit",
              "bytedance/seedance-2.5/text-to-video",
              "bytedance/seedance-2.5/image-to-video",
              "bytedance/seedance-2.0/text-to-video",
              "bytedance/seedance-2.0/image-to-video",
              "alibaba/wan-3.0/text-to-video",
              "alibaba/wan-3.0/image-to-video",
              "alibaba/wan-2.7/text-to-video",
              "alibaba/wan-2.7/image-to-video"
            ],
            "example": "google/nano-banana-2/text-to-image"
          },
          "prompt": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100000,
            "description": "Prompt text."
          },
          "negative_prompt": {
            "type": "string",
            "maxLength": 1000,
            "description": "Optional text describing what to avoid."
          },
          "num_outputs": {
            "type": "integer",
            "minimum": 1,
            "maximum": 16,
            "default": 1,
            "description": "Number of output images for text-to-image models. Each returned image is billed."
          },
          "duration": {
            "type": "integer",
            "minimum": 1,
            "maximum": 600,
            "description": "Video length in seconds. Required for video models, which accept 4 to 15 and bill per second."
          },
          "aspect_ratio": {
            "type": "string",
            "enum": [
              "16:9",
              "9:16",
              "4:3",
              "3:4",
              "1:1",
              "21:9"
            ],
            "default": "16:9",
            "description": "Output aspect ratio."
          },
          "resolution": {
            "type": "string",
            "enum": [
              "0.5k",
              "1k",
              "2k",
              "4k",
              "480p",
              "720p",
              "1080p"
            ],
            "description": "Output resolution. Image models use 0.5k to 4k, video models 480p to 4k; each model supports a subset. Also selects the price tier; a resolution the model has no price for is rejected with 400 VALIDATION_ERROR."
          },
          "image_urls": {
            "type": "array",
            "items": {
              "type": "string",
              "format": "uri"
            },
            "maxItems": 32,
            "description": "Public http(s) URLs of input images: source images for edit models (required), or the first frame for image-to-video models (required)."
          },
          "parameters": {
            "type": "object",
            "additionalProperties": true,
            "description": "Model-specific options forwarded to the provider, for example output_format (png, jpeg, webp), last_image (end frame URL), reference_images, reference_videos, reference_audios (URL arrays), generate_audio and enable_web_search (booleans)."
          },
          "webhook_url": {
            "type": "string",
            "format": "uri",
            "maxLength": 2048,
            "description": "Optional webhook URL for task completion or failure callbacks."
          },
          "nsfw_filter": {
            "type": "boolean",
            "default": false,
            "description": "Screen the prompt and input images with the NSFW filter before generating. Blocked requests return 400 CONTENT_BLOCKED and are not charged. Always on in the EggAPI playground."
          }
        }
      },
      "TaskResponse": {
        "type": "object",
        "properties": {
          "data": {
            "$ref": "#/components/schemas/Task"
          },
          "error": {
            "type": "null"
          }
        }
      },
      "Task": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Task ID, such as gen_3f2a9c1d-7b4."
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "processing",
              "completed",
              "failed"
            ]
          },
          "model": {
            "type": "string",
            "description": "Model ID from the request."
          },
          "type": {
            "type": "string",
            "enum": [
              "image_generate",
              "image_edit",
              "video_generate"
            ]
          },
          "output": {
            "type": "object",
            "properties": {
              "url": {
                "type": "string",
                "format": "uri"
              },
              "urls": {
                "type": "array",
                "items": {
                  "type": "string",
                  "format": "uri"
                }
              },
              "width": {
                "type": "integer"
              },
              "height": {
                "type": "integer"
              },
              "duration_seconds": {
                "type": "integer",
                "description": "Video length in seconds, when reported."
              }
            }
          },
          "error": {
            "type": "string",
            "nullable": true
          },
          "cost": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "started_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          },
          "completed_at": {
            "type": "string",
            "format": "date-time",
            "nullable": true
          }
        }
      },
      "TaskListResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "items": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/Task"
                }
              },
              "pagination": {
                "$ref": "#/components/schemas/Pagination"
              }
            }
          },
          "error": {
            "type": "null"
          }
        }
      },
      "UsageRecord": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "task_id": {
            "type": "string",
            "nullable": true
          },
          "model": {
            "type": "string",
            "description": "Model ID."
          },
          "type": {
            "type": "string",
            "description": "Usage kind: image, edit, or video for the published models."
          },
          "units": {
            "type": "number"
          },
          "unit_cost": {
            "type": "string"
          },
          "total_cost": {
            "type": "string"
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "input": {
            "type": "object"
          },
          "output": {
            "type": "object"
          },
          "status": {
            "type": "string"
          }
        }
      },
      "UsageListResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "items": {
                "type": "array",
                "items": {
                  "$ref": "#/components/schemas/UsageRecord"
                }
              },
              "pagination": {
                "$ref": "#/components/schemas/Pagination"
              }
            }
          },
          "error": {
            "type": "null"
          }
        }
      },
      "UsageSummary": {
        "type": "object",
        "properties": {
          "model": {
            "type": "string",
            "description": "Model ID."
          },
          "total_units": {
            "type": "number"
          },
          "total_cost": {
            "type": "string"
          },
          "request_count": {
            "type": "integer"
          }
        }
      },
      "UsageSummaryResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/UsageSummary"
            }
          },
          "error": {
            "type": "null"
          }
        }
      },
      "Pagination": {
        "type": "object",
        "properties": {
          "page": {
            "type": "integer"
          },
          "per_page": {
            "type": "integer"
          },
          "total": {
            "type": "integer"
          },
          "total_pages": {
            "type": "integer"
          }
        }
      },
      "ErrorResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "null"
          },
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "BAD_REQUEST",
                  "VALIDATION_ERROR",
                  "UNAUTHORIZED",
                  "FORBIDDEN",
                  "INSUFFICIENT_BALANCE",
                  "NOT_FOUND",
                  "RATE_LIMITED",
                  "INTERNAL_ERROR",
                  "UPSTREAM_ERROR",
                  "SERVICE_UNAVAILABLE"
                ]
              },
              "message": {
                "type": "string"
              }
            }
          }
        }
      },
      "UploadResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "object",
            "properties": {
              "files": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "url": {
                      "type": "string",
                      "format": "uri",
                      "description": "Public URL to pass to a model."
                    },
                    "key": {
                      "type": "string",
                      "description": "Storage key."
                    },
                    "content_type": {
                      "type": "string",
                      "example": "image/png"
                    },
                    "size": {
                      "type": "integer",
                      "description": "Size in bytes."
                    }
                  }
                }
              }
            }
          },
          "error": {
            "type": "object",
            "nullable": true
          }
        }
      }
    }
  }
}
