GPT Image 2.5 Ext
curl --request POST \
--url https://api.freemodel.app/v1/images/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "<string>",
"prompt": "<string>",
"version": "<string>",
"resolution": "<string>",
"size": "<string>",
"n": 123,
"image_urls": [
"<string>"
]
}
'import requests
url = "https://api.freemodel.app/v1/images/generations"
payload = {
"model": "<string>",
"prompt": "<string>",
"version": "<string>",
"resolution": "<string>",
"size": "<string>",
"n": 123,
"image_urls": ["<string>"]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: '<string>',
prompt: '<string>',
version: '<string>',
resolution: '<string>',
size: '<string>',
n: 123,
image_urls: ['<string>']
})
};
fetch('https://api.freemodel.app/v1/images/generations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.freemodel.app/v1/images/generations",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => '<string>',
'prompt' => '<string>',
'version' => '<string>',
'resolution' => '<string>',
'size' => '<string>',
'n' => 123,
'image_urls' => [
'<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.freemodel.app/v1/images/generations"
payload := strings.NewReader("{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"version\": \"<string>\",\n \"resolution\": \"<string>\",\n \"size\": \"<string>\",\n \"n\": 123,\n \"image_urls\": [\n \"<string>\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.freemodel.app/v1/images/generations")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"version\": \"<string>\",\n \"resolution\": \"<string>\",\n \"size\": \"<string>\",\n \"n\": 123,\n \"image_urls\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.freemodel.app/v1/images/generations")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"version\": \"<string>\",\n \"resolution\": \"<string>\",\n \"size\": \"<string>\",\n \"n\": 123,\n \"image_urls\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_bodyImage Series
GPT Image 2.5 Ext
Generate 1K–4K images per delivered image with gpt-image-2.5-ext.
POST
/
v1
/
images
/
generations
GPT Image 2.5 Ext
curl --request POST \
--url https://api.freemodel.app/v1/images/generations \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "<string>",
"prompt": "<string>",
"version": "<string>",
"resolution": "<string>",
"size": "<string>",
"n": 123,
"image_urls": [
"<string>"
]
}
'import requests
url = "https://api.freemodel.app/v1/images/generations"
payload = {
"model": "<string>",
"prompt": "<string>",
"version": "<string>",
"resolution": "<string>",
"size": "<string>",
"n": 123,
"image_urls": ["<string>"]
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
model: '<string>',
prompt: '<string>',
version: '<string>',
resolution: '<string>',
size: '<string>',
n: 123,
image_urls: ['<string>']
})
};
fetch('https://api.freemodel.app/v1/images/generations', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.freemodel.app/v1/images/generations",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'model' => '<string>',
'prompt' => '<string>',
'version' => '<string>',
'resolution' => '<string>',
'size' => '<string>',
'n' => 123,
'image_urls' => [
'<string>'
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.freemodel.app/v1/images/generations"
payload := strings.NewReader("{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"version\": \"<string>\",\n \"resolution\": \"<string>\",\n \"size\": \"<string>\",\n \"n\": 123,\n \"image_urls\": [\n \"<string>\"\n ]\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.freemodel.app/v1/images/generations")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"version\": \"<string>\",\n \"resolution\": \"<string>\",\n \"size\": \"<string>\",\n \"n\": 123,\n \"image_urls\": [\n \"<string>\"\n ]\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.freemodel.app/v1/images/generations")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"model\": \"<string>\",\n \"prompt\": \"<string>\",\n \"version\": \"<string>\",\n \"resolution\": \"<string>\",\n \"size\": \"<string>\",\n \"n\": 123,\n \"image_urls\": [\n \"<string>\"\n ]\n}"
response = http.request(request)
puts response.read_bodygpt-image-2.5-ext is the canonical GPT Image 2.5 Ext route. It bills per delivered image, not by tokens. Flare is the default. Send version: "sunburst" for Sunburst on this model ID, or use gpt-image-2.5-ext-sunburst.
| Property | Value |
|---|---|
| Model ID | gpt-image-2.5-ext |
| Versions | flare (default) or sunburst |
| Resolutions | 1K, 2K, 4K (default 1K) |
| Size | auto (default) or a supported ratio |
| Count | integer n from 1 to 4 (default 1) |
| References | optional, up to 16 public URLs or PNG/JPEG/WebP Data URLs |
| Response | data[].url when the request waits successfully |
| Resolution | Price per delivered image |
|---|---|
1K | $0.0085 (0.85 credits) |
2K | $0.014 (1.4 credits) |
4K | $0.021 (2.1 credits) |
quality, transparency, or custom pixel sizes such as 1024x1024.
string
required
Set to
gpt-image-2.5-ext.string
required
Describe the subject, composition, lighting, and style. The prompt must be a non-empty string of at most 100,000 characters.
string
default:"flare"
Use
flare or sunburst.string
default:"1K"
Use
1K, 2K, or 4K. This selects the billed output tier.string
default:"auto"
Use
auto, 1:1, 16:9, 9:16, 4:3, 3:4, 3:2, 2:3, 5:4, 4:5, or 21:9.integer
default:"1"
Request 1 to 4 images. The gateway reserves
n times the resolution price, then settles the actual returned count.string[]
Up to 16 publicly reachable
http or https image URLs, or data:image/png, data:image/jpeg, or data:image/webp Data URLs. Loopback, private, and credentialed URLs are rejected. The whole JSON body is still limited by the gateway request-size cap (default 10 MiB).Request
A normal request waits for a terminal result (default 180 seconds). On success it returns image URLs. If generation is still running, the response is HTTP202 with a gateway task object. Poll GET /v1/tasks/{id} with the same API key. Do not treat that object as an upstream Apimart payload.
curl https://api.freemodel.app/v1/images/generations \
-H "Authorization: Bearer $FREEMODEL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2.5-ext",
"prompt": "Preserve the product and replace the background with warm linen",
"resolution": "4K",
"size": "16:9",
"n": 2,
"image_urls": ["https://example.com/product.png"]
}'
{
"created": 1784045139,
"data": [
{ "url": "https://cdn.example.com/image-1.png" },
{ "url": "https://cdn.example.com/image-2.png" }
]
}
Run asynchronously
SendPrefer: respond-async to receive HTTP 202 immediately. Include Idempotency-Key (1–200 characters) if you need the gateway to replay the same client submission. Read Location or x-gateway-task-id, then poll GET /v1/tasks/{id}.
curl https://api.freemodel.app/v1/images/generations \
-H "Authorization: Bearer $FREEMODEL_API_KEY" \
-H "Content-Type: application/json" \
-H "Prefer: respond-async" \
-H "Idempotency-Key: lantern-4k-001" \
-d '{
"model": "gpt-image-2.5-ext",
"version": "sunburst",
"prompt": "An indigo paper lantern on linen, editorial lighting",
"resolution": "1K",
"size": "auto",
"n": 1
}'
The gateway reserves the requested
n and resolution up front. A successful task charges the delivered image count against that immutable price version. Explicit failure or cancellation releases the reservation. Missing, empty, oversized, or invalid results keep the reservation for reconciliation. Repeated status polls do not charge twice.Open the model playground
Run the same route from the FreeModel model page.