Playground
curl --request POST \
--url https://api.widerouter.com/v1/task/submit \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "<string>",
"input": {
"input.prompt": "<string>",
"input.n": 123,
"input.aspect_ratio": "<string>",
"input.image_size": "<string>",
"input.images": [
"<string>"
]
},
"callback_url": "<string>"
}
'import requests
url = "https://api.widerouter.com/v1/task/submit"
payload = {
"model": "<string>",
"input": {
"input.prompt": "<string>",
"input.n": 123,
"input.aspect_ratio": "<string>",
"input.image_size": "<string>",
"input.images": ["<string>"]
},
"callback_url": "<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>',
input: {
'input.prompt': '<string>',
'input.n': 123,
'input.aspect_ratio': '<string>',
'input.image_size': '<string>',
'input.images': ['<string>']
},
callback_url: '<string>'
})
};
fetch('https://api.widerouter.com/v1/task/submit', 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.widerouter.com/v1/task/submit",
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>',
'input' => [
'input.prompt' => '<string>',
'input.n' => 123,
'input.aspect_ratio' => '<string>',
'input.image_size' => '<string>',
'input.images' => [
'<string>'
]
],
'callback_url' => '<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.widerouter.com/v1/task/submit"
payload := strings.NewReader("{\n \"model\": \"<string>\",\n \"input\": {\n \"input.prompt\": \"<string>\",\n \"input.n\": 123,\n \"input.aspect_ratio\": \"<string>\",\n \"input.image_size\": \"<string>\",\n \"input.images\": [\n \"<string>\"\n ]\n },\n \"callback_url\": \"<string>\"\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.widerouter.com/v1/task/submit")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"<string>\",\n \"input\": {\n \"input.prompt\": \"<string>\",\n \"input.n\": 123,\n \"input.aspect_ratio\": \"<string>\",\n \"input.image_size\": \"<string>\",\n \"input.images\": [\n \"<string>\"\n ]\n },\n \"callback_url\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.widerouter.com/v1/task/submit")
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 \"input\": {\n \"input.prompt\": \"<string>\",\n \"input.n\": 123,\n \"input.aspect_ratio\": \"<string>\",\n \"input.image_size\": \"<string>\",\n \"input.images\": [\n \"<string>\"\n ]\n },\n \"callback_url\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"id": "task_dksUgWLYX4jIVueCACD8KwJzjR5JhRsI",
"status": "queued",
"created_at": 1788104112
}
Nano Banana series
Playground
Submit a real generation task from this page, then poll it with the returned task id.
POST
/
v1
/
task
/
submit
Playground
curl --request POST \
--url https://api.widerouter.com/v1/task/submit \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"model": "<string>",
"input": {
"input.prompt": "<string>",
"input.n": 123,
"input.aspect_ratio": "<string>",
"input.image_size": "<string>",
"input.images": [
"<string>"
]
},
"callback_url": "<string>"
}
'import requests
url = "https://api.widerouter.com/v1/task/submit"
payload = {
"model": "<string>",
"input": {
"input.prompt": "<string>",
"input.n": 123,
"input.aspect_ratio": "<string>",
"input.image_size": "<string>",
"input.images": ["<string>"]
},
"callback_url": "<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>',
input: {
'input.prompt': '<string>',
'input.n': 123,
'input.aspect_ratio': '<string>',
'input.image_size': '<string>',
'input.images': ['<string>']
},
callback_url: '<string>'
})
};
fetch('https://api.widerouter.com/v1/task/submit', 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.widerouter.com/v1/task/submit",
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>',
'input' => [
'input.prompt' => '<string>',
'input.n' => 123,
'input.aspect_ratio' => '<string>',
'input.image_size' => '<string>',
'input.images' => [
'<string>'
]
],
'callback_url' => '<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.widerouter.com/v1/task/submit"
payload := strings.NewReader("{\n \"model\": \"<string>\",\n \"input\": {\n \"input.prompt\": \"<string>\",\n \"input.n\": 123,\n \"input.aspect_ratio\": \"<string>\",\n \"input.image_size\": \"<string>\",\n \"input.images\": [\n \"<string>\"\n ]\n },\n \"callback_url\": \"<string>\"\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.widerouter.com/v1/task/submit")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"model\": \"<string>\",\n \"input\": {\n \"input.prompt\": \"<string>\",\n \"input.n\": 123,\n \"input.aspect_ratio\": \"<string>\",\n \"input.image_size\": \"<string>\",\n \"input.images\": [\n \"<string>\"\n ]\n },\n \"callback_url\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.widerouter.com/v1/task/submit")
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 \"input\": {\n \"input.prompt\": \"<string>\",\n \"input.n\": 123,\n \"input.aspect_ratio\": \"<string>\",\n \"input.image_size\": \"<string>\",\n \"input.images\": [\n \"<string>\"\n ]\n },\n \"callback_url\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"id": "task_dksUgWLYX4jIVueCACD8KwJzjR5JhRsI",
"status": "queued",
"created_at": 1788104112
}
Fill in your API key and a prompt, then send. This hits the live API — the same
endpoint your code would call.
A finished task carries an
Requests sent from this page are real and are billed to your key.
A single 1K image costs about $0.02–0.09 depending on the model. Nothing here
is a sandbox or a mock.
Parameters
string
required
Which model to run. Accepts
gemini-3-pro-image or gemini-3.1-flash-image,
matched exactly — no aliases, no -preview suffixes.object
required
The generation parameters. Any key not listed below is rejected with
invalid_params.Show input
Show input
string
required
What to generate. 1–32000 bytes.
integer
default:"1"
How many images to produce, 1 to 4. Each one is a separate entry in
outputs.string
One of
1:1 2:3 3:2 3:4 4:3 4:5 5:4 9:16 16:9 21:9.
Omit it to get a square image, or to follow the source image when you pass
reference images.string
default:"1K"
1K, 2K or 4K. Case-sensitive. This scales the whole frame, so a
21:9 image at 4K comes back 6336 × 2688.string[]
Reference images to edit or compose from, up to 14. Each entry is an
https URL or a base64 data URI.string
An
https URL to POST the finished task to, so you can skip polling. Must be
https — anything else is rejected at submit time.What comes back
Submitting returns immediately, in well under a second. The image is not in this response — generation happens in the background.| Field | Type | Notes |
|---|---|---|
id | string | The task id. Everything else needs it. |
status | string | queued on a fresh task. |
created_at | integer | Unix seconds, UTC. |
{
"id": "task_dksUgWLYX4jIVueCACD8KwJzjR5JhRsI",
"status": "queued",
"created_at": 1788104112
}
Then poll for the image
This playground covers the create call only. Take theid from the response
above and read the task until status reaches completed or failed — expect
15–40 seconds for a 1K image.
curl https://api.widerouter.com/v1/task/$TASK_ID \
-H "Authorization: Bearer $WIDEROUTER_API_KEY"
outputs array of image URLs:
{
"id": "task_dksUgWLYX4jIVueCACD8KwJzjR5JhRsI",
"status": "completed",
"outputs": ["https://…/task_dksUgWLYX4jIVueCACD8KwJzjR5JhRsI_0.jpg"],
"counts": { "requested": 1, "succeeded": 1, "failed": 0 }
}
Output URLs are unauthenticated and expire 24 hours after the task finishes.
Copy anything you want to keep into your own storage.
Next steps
Overview
Every parameter, resolution tier and measured latency for the series.
Async task API
The polling loop, callbacks and the full error table.