OpenAI's GPT Image 2 Text-to-Image generates high-quality images from natural-language prompts. Ready-to-use REST inference API, best performance, no coldstarts, affordable pricing.
Integration Steps
Asynchronous Polling1.8s for up to 180s.succeeded / failed / cancelled.output_payload.assets[] URLs.Step 1 · Create Request
Submit generation input. Choose a backend language example below.
curl -X POST https://api.openoctopus.com/v1/images/generations \\
-H "Content-Type: application/json" \\
-H "Authorization: Bearer ooq_your_api_key" \\
-d '{
"model": "openoctopus/gpt-image-2-text-input",
"prompt": "a premium octopus mascot, orange and black, clean background"
}'Poll Task Status
Use the task ID from create response to poll execution status.
curl https://api.openoctopus.com/v1/tasks/task_id_from_previous_response \
-H "Authorization: Bearer ooq_your_api_key"const timeoutMs = 180000;
const intervalMs = 1800;
const startedAt = Date.now();
while (Date.now() - startedAt < timeoutMs) {
const r = await fetch("https://api.openoctopus.com/v1/tasks/task_id_from_previous_response", {
headers: { Authorization: "Bearer " + process.env.OPENOCTOPUS_API_KEY },
});
const task = await r.json();
if (!r.ok) throw new Error(task?.error?.message ?? "task query failed");
if (task.status === "queued" || task.status === "processing") {
await new Promise((resolve) => setTimeout(resolve, intervalMs));
continue;
}
if (task.status === "succeeded") {
console.log(task.output_payload);
break;
}
throw new Error(task?.error_message ?? "task failed");
}import time, requests
timeout_s = 180
interval_s = 1.8
started = time.time()
while time.time() - started < timeout_s:
resp = requests.get(
"https://api.openoctopus.com/v1/tasks/task_id_from_previous_response",
headers={"Authorization": f"Bearer {OPENOCTOPUS_API_KEY}"},
timeout=30,
)
task = resp.json()
if resp.status_code >= 400:
raise RuntimeError(task.get("error", {}).get("message", "task query failed"))
status = task.get("status")
if status in ("queued", "processing"):
time.sleep(interval_s)
continue
if status == "succeeded":
print(task.get("output_payload"))
break
raise RuntimeError(task.get("error_message", "task failed"))Request Example (From Internal)
{
"model": "openoctopus/your-model",
"prompt": "example",
"input": {
"aspect_ratio": "1:1",
"resolution": "1k",
"quality": "medium",
"output_format": "png",
"enable_sync_mode": "false",
"enable_base64_output": false
}
}Submit Response Example
{
"id": "00000000-0000-0000-0000-000000000000",
"status": "queued",
"model": "openoctopus/your-model"
}Input Schema (Standard + Provider Extension)
Standard request contract merged with this model's upstream input parameters.
| Field | Type | Required | Description | Example |
|---|---|---|---|---|
| aspect_ratio | string | No | The aspect ratio of the generated image. Options: "1:1", "3:2", "2:3", "3:4", "4:3", "4:5", "5:4", "9:16", "16:9", "21:9" | 1:1 |
| resolution | string | No | The resolution of the output image. Default: "1k". Options: "1k", "2k", "4k" | 1k |
| quality | string | No | The quality of the generated image. Higher quality costs more. Default: "medium". Options: "low", "medium", "high" | medium |
| output_format | string | No | The format of the output image. Default: "png". Options: "png", "jpeg", "webp" | png |
| enable_sync_mode | boolean | No | If set to true, the function will wait for the result to be generated and uploaded before returning the response. This property is only available through the API. | false |
| enable_base64_output | boolean | No | If enabled, the output will be encoded into a BASE64 string instead of a URL. This property is only available through the API. | false |
{
"standard": {
"model": "public model slug (required)",
"prompt": "user prompt (required)",
"input": "provider-specific options (optional object)"
},
"providerExtension": {
"params": [
{
"enum": [
"1:1",
"3:2",
"2:3",
"4:3",
"16:9",
"9:16",
"3:4",
"5:4",
"21:9"
],
"name": "aspect_ratio",
"type": "string",
"example": "1:1",
"required": false,
"description": "The aspect ratio of the generated image. Options: \"1:1\", \"3:2\", \"2:3\", \"3:4\", \"4:3\", \"4:5\", \"5:4\", \"9:16\", \"16:9\", \"21:9\"",
"exposedToCustomer": true
},
{
"enum": [
"1k",
"2k",
"4k"
],
"name": "resolution",
"type": "string",
"example": "1k",
"required": false,
"description": "The resolution of the output image. Default: \"1k\". Options: \"1k\", \"2k\", \"4k\"",
"exposedToCustomer": true
},
{
"enum": [
"medium",
"low",
"high"
],
"name": "quality",
"type": "string",
"example": "medium",
"required": false,
"description": "The quality of the generated image. Higher quality costs more. Default: \"medium\". Options: \"low\", \"medium\", \"high\"",
"exposedToCustomer": true
},
{
"enum": [
"png",
"jpeg",
"webp"
],
"name": "output_format",
"type": "string",
"example": "png",
"required": false,
"description": "The format of the output image. Default: \"png\". Options: \"png\", \"jpeg\", \"webp\"",
"exposedToCustomer": true
},
{
"name": "enable_sync_mode",
"type": "boolean",
"example": "false",
"required": false,
"description": "If set to true, the function will wait for the result to be generated and uploaded before returning the response. This property is only available through the API.",
"exposedToCustomer": false
},
{
"name": "enable_base64_output",
"type": "boolean",
"example": "false",
"required": false,
"description": "If enabled, the output will be encoded into a BASE64 string instead of a URL. This property is only available through the API.",
"exposedToCustomer": false
}
]
}
}Output Schema (Standard + Provider Extension)
Standard output contract merged with provider extension fields.
Note: integrate against output_payload.assets[]. raw is optional and may be omitted by endpoint policy.
| Field | Type | Exposed | Description | Example |
|---|---|---|---|---|
| model | string | Yes | Model ID used for the prediction. | - |
| outputs | array of string | Yes | Array of URLs to the generated content (empty when status is not completed). | - |
| status | string | Yes | Status of the task: created, processing, completed, or failed. | - |
| urls | object | Yes | Object containing related API endpoints. | [object Object] |
| created_at | string (date-time) | Yes | ISO timestamp of when the request was created (e.g., "2023-04-01T12:34:56.789Z"). | - |
| has_nsfw_contents | array of boolean | Yes | Array of boolean values indicating NSFW detection for each output. | - |
| id | string | Yes | Unique identifier for the prediction, the ID of the prediction to get. | - |
{
"standard": {
"id": "task id",
"status": "queued | processing | succeeded | failed | cancelled",
"queue": {
"enabled": "whether OpenOctopus local queue is enabled for this model",
"position": "1-based queue position while queued, 0 while processing, null when unavailable",
"size": "current queued request count for this model",
"concurrency": "local concurrent upstream submissions allowed for this model",
"upstreamQueueSupported": "whether the upstream provider has a reliable queue",
"upstreamCancelSupported": "whether the upstream provider supports cancellation"
},
"asset_storage": {
"provider": "supabase | aliyun-oss | tencent-cos",
"inputBucket": "bucket used for uploaded reference media",
"outputBucket": "bucket used for generated media",
"custom": "true when this model overrides default system asset storage"
},
"capability": "image_generation | video_generation",
"output_payload": {
"format": "openoctopus.image.output.v1 | openoctopus.video.output.v1",
"assets": "normalized output assets",
"raw": "optional sanitized debug payload (may be omitted depending on endpoint policy)"
}
},
"providerExtension": {
"fields": [
{
"name": "model",
"type": "string",
"description": "Model ID used for the prediction.",
"exposedToCustomer": true
},
{
"name": "outputs",
"type": "array of string",
"description": "Array of URLs to the generated content (empty when status is not completed).",
"exposedToCustomer": true
},
{
"name": "status",
"type": "string",
"description": "Status of the task: created, processing, completed, or failed.",
"exposedToCustomer": true
},
{
"name": "urls",
"type": "object",
"example": "[object Object]",
"description": "Object containing related API endpoints.",
"exposedToCustomer": true
},
{
"name": "created_at",
"type": "string (date-time)",
"description": "ISO timestamp of when the request was created (e.g., \"2023-04-01T12:34:56.789Z\").",
"exposedToCustomer": true
},
{
"name": "has_nsfw_contents",
"type": "array of boolean",
"description": "Array of boolean values indicating NSFW detection for each output.",
"exposedToCustomer": true
},
{
"name": "id",
"type": "string",
"description": "Unique identifier for the prediction, the ID of the prediction to get.",
"exposedToCustomer": true
}
]
}
}Final Output Example (Normalized)
{
"capability": "image_generation",
"status": "succeeded",
"output_payload": {
"format": "openoctopus.image.output.v1",
"assets": [
{
"type": "image",
"url": "https://example.com/result.png",
"mimeType": "image/png"
}
],
"raw": {
"model": "example",
"outputs": "example",
"status": "example",
"urls": "example",
"created_at": "example",
"has_nsfw_contents": "example",
"id": "example"
}
}
}Step 4 · Error Handling Guide
Error codes below are loaded from internal gateway error definitions and should be treated as source of truth.
| Code | HTTP | Retryable | Category | Message |
|---|---|---|---|---|
| invalid_request | 400 | No | validation | The request payload is invalid. Check the required fields and try again. |
| unauthorized | 401 | No | auth | Authentication is required for this request. |
| invalid_api_key | 401 | No | auth | The API key is invalid or inactive. |
| insufficient_balance | 402 | No | billing | Your wallet balance is insufficient. Please top up and try again. |
| model_not_available | 404 | No | routing | The requested model is currently unavailable. |
| task_not_found | 404 | No | task | The requested task could not be found. |
| file_not_found | 404 | No | asset | The requested generated file is not available. |
| provider_offline | 503 | Yes | upstream | The selected model is temporarily unavailable. Please retry later. |
| provider_model_inactive | 503 | Yes | routing | The selected model is temporarily unavailable. Please retry later. |
| provider_credential_missing | 503 | Yes | system | The service is temporarily unavailable for this model. Please retry later. |
| provider_credential_incomplete | 503 | Yes | system | The service is temporarily unavailable for this model. Please retry later. |
| provider_credential_unusable | 503 | Yes | system | The service is temporarily unavailable for this model. Please retry later. |
| provider_credential_legacy | 503 | Yes | system | The service is temporarily unavailable for this model. Please retry later. |
| provider_credential_unavailable | 503 | Yes | system | The service is temporarily unavailable for this model. Please retry later. |
| provider_credential_decrypt_failed | 503 | Yes | system | The service is temporarily unavailable for this model. Please retry later. |
| model_billing_not_configured | 503 | No | system | The selected model is temporarily unavailable. Please retry later. |
| provider_pricing_not_configured | 503 | No | system | The selected model is temporarily unavailable. Please retry later. |
| database_operation_failed | 503 | Yes | system | The service could not access required internal records. Please retry later. |
| billing_resolution_failed | 503 | Yes | system | The selected model pricing could not be evaluated. Please retry later. |
| request_record_write_failed | 503 | Yes | system | The request could not be recorded internally. Please retry later. |
| api_key_touch_failed | 503 | Yes | system | The request was accepted but internal key tracking failed. Please retry later. |
| queue_unavailable | 503 | Yes | system | The internal job queue is temporarily unavailable. Please retry later. |
| provider_submit_failed | 502 | Yes | upstream | The generation provider could not accept the request. Please retry shortly. |
| provider_poll_failed | 502 | Yes | upstream | The generation provider could not complete the request. Please retry shortly. |
| upstream_failed | 502 | Yes | upstream | The generation provider failed to complete the request. Please retry shortly. |
| content_policy_violation | 400 | No | safety | The prompt or image was rejected by the provider safety policy. Please adjust the content and try again. |
| upstream_timeout | 504 | Yes | upstream | The generation request timed out. Please retry shortly. |
| upstream_result_missing | 502 | Yes | upstream | The generation provider returned an incomplete result. Please retry shortly. |
| video_output_missing | 502 | Yes | upstream | The generation provider returned an incomplete result. Please retry shortly. |
| service_unavailable | 503 | Yes | system | The service is temporarily unavailable. Please retry later. |
| internal_error | 500 | Yes | system | The service encountered an unexpected error. Please retry later. |
task.status=failed, always read error.code and match the table above; retry only when retryable=true.