# gpt-image-2 — Scenepond API

Model ID: `gpt-image-2`

Model developer: OpenAI

Source page: https://open.scenepond.ai/en/models/gpt-image-2#api

Reviewed: 2026-10-11

Base URL: `https://open.scenepond.ai/v1`

Authenticate every request with Authorization: Bearer and your Scenepond API key. Keep the key on your server.

## Scenepond asynchronous tasks

`POST /v1/tasks`

### Minimum request

#### cURL

```bash
curl --fail-with-body -X POST "https://open.scenepond.ai/v1/tasks" \
  -H "Authorization: Bearer $SCENEPOND_API_KEY" \
  -H "Content-Type: application/json" \
  --data-binary @- <<'JSON'
{
  "model": "gpt-image-2",
  "parameters": {
    "prompt": "A cat walking on a quiet beach",
    "count": 1,
    "size": "1024x1024",
    "quality": "low"
  }
}
JSON
```

#### Python

```python
import os
import json
from urllib.parse import quote
from urllib.request import Request, urlopen

payload = json.loads("{\n  \"model\": \"gpt-image-2\",\n  \"parameters\": {\n    \"prompt\": \"A cat walking on a quiet beach\",\n    \"count\": 1,\n    \"size\": \"1024x1024\",\n    \"quality\": \"low\"\n  }\n}")

request = Request(
    "https://open.scenepond.ai/v1/tasks",
    headers={
        "Authorization": "Bearer " + os.environ["SCENEPOND_API_KEY"],
        "Content-Type": "application/json",
    },
    data=json.dumps(payload).encode("utf-8"),
    method="POST",
)
with urlopen(request) as response:
    result = json.load(response)
print(json.dumps(result, indent=2))
```

#### JavaScript

```javascript
const response = await fetch("https://open.scenepond.ai/v1/tasks", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.SCENEPOND_API_KEY}`,
    "Content-Type": "application/json"
  },
  body: JSON.stringify({
  "model": "gpt-image-2",
  "parameters": {
    "prompt": "A cat walking on a quiet beach",
    "count": 1,
    "size": "1024x1024",
    "quality": "low"
  }
})
});
if (!response.ok) throw new Error(`API error: ${response.status} ${await response.text()}`);
const result = await response.json();
console.log(result);
```

### Request parameters

- `model` — **Required**; `string`. Use this exact public model ID.
  - Constraints: `const = "gpt-image-2"`

- `parameters` — **Required**; `object`. Generation parameters for this model.

### Fields in parameters

These fields apply when parameters is supplied. A required child does not make its optional parent required.

- `parameters.prompt` — **Required**; `string`. Describe the subject, scene, and desired generation.
  - Constraints: `length = 1..32000`

- `parameters.count` — **Optional**; `integer`. Number of images requested in this task.
  - Constraints: `minimum = 1`; `maximum = 10`

- `parameters.size` — **Optional**; `string`. Output image dimensions. Use auto or a supported width x height.
  - Constraints: `Edges must be multiples of 16`; `maximum edge = 3840`; `pixels = 655360..8294400`; `maximum aspect ratio = 3:1`

- `parameters.quality` — **Optional**; `string`. Requested image quality tier.
  - Constraints: `enum = auto, low, medium, high`

- `parameters.image_urls` — **Optional**; `string[]`. Optional reference images. Supplying these selects image editing.
  - Constraints: `items = 1..16`

- `parameters.mask_url` — **Optional**; `string`. Optional mask image URL for image editing.

- `parameters.background` — **Optional**; `string`. Requested background treatment.
  - Constraints: `enum = auto, opaque, transparent`

- `parameters.output_format` — **Optional**; `string`. Encoding format of the generated image.
  - Constraints: `enum = png, jpeg, webp`

- `parameters.output_compression` — **Optional**; `integer`. Output compression percentage.
  - Constraints: `minimum = 0`; `maximum = 100`

- `parameters.moderation` — **Optional**; `string`. Image moderation level.
  - Constraints: `enum = auto, low`


### Illustrative responses

Response examples show the structure only. IDs, URLs, and values are placeholders.

#### Submission response

```json
{
  "task_id": "task_EXAMPLE",
  "model": "gpt-image-2",
  "status": "queued",
  "progress": 0,
  "created_at": 1700000000,
  "finished_at": 0,
  "error": null,
  "links": {
    "self": "/v1/tasks/task_EXAMPLE",
    "artifacts": "/v1/tasks/task_EXAMPLE/artifacts"
  }
}
```

#### Completed task status

```json
{
  "task_id": "task_EXAMPLE",
  "model": "gpt-image-2",
  "status": "succeeded",
  "progress": 100,
  "created_at": 1700000000,
  "finished_at": 1700000060,
  "error": null,
  "links": {
    "self": "/v1/tasks/task_EXAMPLE",
    "artifacts": "/v1/tasks/task_EXAMPLE/artifacts"
  }
}
```

#### Artifact listing

```json
{
  "task_id": "task_EXAMPLE",
  "artifacts": [
    {
      "key": "image_0",
      "type": "image",
      "content_url": "https://open.scenepond.ai/v1/tasks/task_EXAMPLE/artifacts/image_0/content"
    }
  ]
}
```

### Follow-up requests

#### 2. Check task status

Poll every few seconds until succeeded or failed.

##### cURL

```bash
curl --fail-with-body -X GET "https://open.scenepond.ai/v1/tasks/$SCENEPOND_TASK_ID" \
  -H "Authorization: Bearer $SCENEPOND_API_KEY"
```

##### Python

```python
import os
import json
from urllib.parse import quote
from urllib.request import Request, urlopen

request = Request(
    "https://open.scenepond.ai/v1/tasks/" + quote(os.environ["SCENEPOND_TASK_ID"], safe="") + "",
    headers={
        "Authorization": "Bearer " + os.environ["SCENEPOND_API_KEY"],
        "Content-Type": "application/json",
    },
    method="GET",
)
with urlopen(request) as response:
    result = json.load(response)
print(json.dumps(result, indent=2))
```

##### JavaScript

```javascript
if (!process.env.SCENEPOND_TASK_ID) throw new Error("Set SCENEPOND_TASK_ID first");
const response = await fetch("https://open.scenepond.ai/v1/tasks/" + encodeURIComponent(process.env.SCENEPOND_TASK_ID) + "", {
  method: "GET",
  headers: {
    "Authorization": `Bearer ${process.env.SCENEPOND_API_KEY}`,
    "Content-Type": "application/json"
  }
});
if (!response.ok) throw new Error(`API error: ${response.status} ${await response.text()}`);
const result = await response.json();
console.log(result);
```

#### 3. Get the results

After succeeded, list artifacts and download each content_url. Keep signed URLs private.

##### cURL

```bash
curl --fail-with-body -X GET "https://open.scenepond.ai/v1/tasks/$SCENEPOND_TASK_ID/artifacts" \
  -H "Authorization: Bearer $SCENEPOND_API_KEY"
```

##### Python

```python
import os
import json
from urllib.parse import quote
from urllib.request import Request, urlopen

request = Request(
    "https://open.scenepond.ai/v1/tasks/" + quote(os.environ["SCENEPOND_TASK_ID"], safe="") + "/artifacts",
    headers={
        "Authorization": "Bearer " + os.environ["SCENEPOND_API_KEY"],
        "Content-Type": "application/json",
    },
    method="GET",
)
with urlopen(request) as response:
    result = json.load(response)
print(json.dumps(result, indent=2))
```

##### JavaScript

```javascript
if (!process.env.SCENEPOND_TASK_ID) throw new Error("Set SCENEPOND_TASK_ID first");
const response = await fetch("https://open.scenepond.ai/v1/tasks/" + encodeURIComponent(process.env.SCENEPOND_TASK_ID) + "/artifacts", {
  method: "GET",
  headers: {
    "Authorization": `Bearer ${process.env.SCENEPOND_API_KEY}`,
    "Content-Type": "application/json"
  }
});
if (!response.ok) throw new Error(`API error: ${response.status} ${await response.text()}`);
const result = await response.json();
console.log(result);
```

### Request notes

- Images and videos use the same task API. Select a model; channel selection is automatic.
- Authenticate every request with Authorization: Bearer and your Scenepond API key. Keep the key on your server.
- Submit once, save task_id, then poll until succeeded or failed. Download results from the artifacts endpoint.
- Creation returns after upstream acceptance. A synchronous upstream may finish before the task ID is returned.
- Do not automatically resubmit a timed-out POST. It may already have created a billable task.
- Parameters and limits vary by model. Only the fields listed for this model are accepted.
