mirror of
https://github.com/Wei-Shaw/sub2api.git
synced 2026-09-21 14:19:18 +08:00
docs: document async image task API
This commit is contained in:
@@ -135,6 +135,7 @@ docs/*
|
||||
!docs/PAYMENT.md
|
||||
!docs/PAYMENT_CN.md
|
||||
!docs/ADMIN_PAYMENT_INTEGRATION_API.md
|
||||
!docs/ASYNC_IMAGE_TASKS.md
|
||||
!docs/legal/
|
||||
!docs/legal/*.md
|
||||
.serena/
|
||||
|
||||
@@ -688,6 +688,12 @@ Simple Mode is designed for individual developers or internal teams who want qui
|
||||
|
||||
---
|
||||
|
||||
## Asynchronous Image Tasks
|
||||
|
||||
Long-running OpenAI/Grok image generation and editing can be submitted through `/v1/images/generations/async` or `/v1/images/edits/async`, then polled at `/v1/images/tasks/{task_id}` without holding a CDN connection open. See [Asynchronous Image Tasks](docs/ASYNC_IMAGE_TASKS.md) for request and response examples.
|
||||
|
||||
---
|
||||
|
||||
## Grok / xAI Support
|
||||
|
||||
Sub2API supports both Grok subscription accounts through xAI OAuth and standard xAI API-key accounts. Both account types forward OpenAI-compatible Responses traffic to xAI.
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
# Asynchronous Image Tasks
|
||||
|
||||
Asynchronous image tasks let clients submit long-running OpenAI-compatible image requests without keeping one HTTP connection open. This avoids proxy/CDN response timeouts such as Cloudflare 524 while preserving the existing image routing, billing, moderation, concurrency, and failover behavior.
|
||||
|
||||
## Endpoints
|
||||
|
||||
The authenticated gateway exposes both `/v1` paths and their existing no-prefix aliases:
|
||||
|
||||
```text
|
||||
POST /v1/images/generations/async
|
||||
POST /v1/images/edits/async
|
||||
GET /v1/images/tasks/{task_id}
|
||||
```
|
||||
|
||||
The aliases are `/images/generations/async`, `/images/edits/async`, and `/images/tasks/{task_id}`.
|
||||
|
||||
Only OpenAI and Grok groups are supported. Requests use the same JSON or multipart payload as the corresponding synchronous endpoint. Streaming image requests are rejected because a polled task returns one final JSON result.
|
||||
|
||||
## Submit a task
|
||||
|
||||
```bash
|
||||
curl -i https://api.example.com/v1/images/generations/async \
|
||||
-H 'Authorization: Bearer sk-...' \
|
||||
-H 'Content-Type: application/json' \
|
||||
-d '{
|
||||
"model": "gpt-image-1",
|
||||
"prompt": "A lighthouse during a winter storm",
|
||||
"size": "1536x1024"
|
||||
}'
|
||||
```
|
||||
|
||||
The server stores the initial task in Redis and responds with `202 Accepted`:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "imgtask_0123456789abcdef",
|
||||
"task_id": "imgtask_0123456789abcdef",
|
||||
"object": "image.generation.task",
|
||||
"status": "processing",
|
||||
"created_at": 1784092800,
|
||||
"expires_at": 1784179200,
|
||||
"poll_url": "/v1/images/tasks/imgtask_0123456789abcdef"
|
||||
}
|
||||
```
|
||||
|
||||
`Location` contains the polling path and `Retry-After: 3` provides the recommended polling interval.
|
||||
|
||||
## Poll a task
|
||||
|
||||
Use the same API key that submitted the task:
|
||||
|
||||
```bash
|
||||
curl https://api.example.com/v1/images/tasks/imgtask_0123456789abcdef \
|
||||
-H 'Authorization: Bearer sk-...'
|
||||
```
|
||||
|
||||
While work is in progress:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "imgtask_0123456789abcdef",
|
||||
"task_id": "imgtask_0123456789abcdef",
|
||||
"object": "image.generation.task",
|
||||
"status": "processing",
|
||||
"created_at": 1784092800,
|
||||
"expires_at": 1784179200
|
||||
}
|
||||
```
|
||||
|
||||
On success, `result` is the unmodified JSON body from the synchronous image API, so URL and base64 response formats both remain supported:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "imgtask_0123456789abcdef",
|
||||
"task_id": "imgtask_0123456789abcdef",
|
||||
"object": "image.generation.task",
|
||||
"status": "completed",
|
||||
"http_status": 200,
|
||||
"image_url": "https://...",
|
||||
"result": {
|
||||
"created": 1784092923,
|
||||
"data": [{"url": "https://..."}]
|
||||
},
|
||||
"created_at": 1784092800,
|
||||
"completed_at": 1784092923,
|
||||
"expires_at": 1784179323
|
||||
}
|
||||
```
|
||||
|
||||
For URL responses, `image_url` mirrors the first `data[].url` for simple clients. On failure, the task reaches `failed` and exposes the original OpenAI-compatible error object where available:
|
||||
|
||||
```json
|
||||
{
|
||||
"id": "imgtask_0123456789abcdef",
|
||||
"task_id": "imgtask_0123456789abcdef",
|
||||
"object": "image.generation.task",
|
||||
"status": "failed",
|
||||
"http_status": 502,
|
||||
"error": {
|
||||
"type": "api_error",
|
||||
"message": "Upstream request failed"
|
||||
},
|
||||
"created_at": 1784092800,
|
||||
"completed_at": 1784092923,
|
||||
"expires_at": 1784179323
|
||||
}
|
||||
```
|
||||
|
||||
All submit and poll responses include `Cache-Control: no-store`, preventing a CDN from caching the `processing` state. Tasks and results expire 24 hours after their latest state update. A task executes for at most 30 minutes.
|
||||
|
||||
Task ownership is scoped to both user and API key. Unknown task IDs and IDs owned by another key both return `404`, avoiding task-existence disclosure. Polling remains available when the completed generation used the key's remaining balance; normal authentication, disabled-key, user, IP, and group checks still apply.
|
||||
Reference in New Issue
Block a user