Generate Image
curl --request POST \
--url https://api.pictory.ai/pictoryapis/v1/aistudio/images \
--header 'Authorization: <authorization>' \
--header 'Content-Type: <content-type>' \
--data '
{
"prompt": "<string>",
"model": "<string>",
"aspectRatio": "<string>",
"style": "<string>",
"referenceImageUrls": [
{}
],
"referenceImageUrl": "<string>",
"trainingPreset": "<string>",
"enhancePrompt": true,
"webhook": "<string>"
}
'import requests
url = "https://api.pictory.ai/pictoryapis/v1/aistudio/images"
payload = {
"prompt": "<string>",
"model": "<string>",
"aspectRatio": "<string>",
"style": "<string>",
"referenceImageUrls": [{}],
"referenceImageUrl": "<string>",
"trainingPreset": "<string>",
"enhancePrompt": True,
"webhook": "<string>"
}
headers = {
"Authorization": "<authorization>",
"Content-Type": "<content-type>"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<authorization>', 'Content-Type': '<content-type>'},
body: JSON.stringify({
prompt: '<string>',
model: '<string>',
aspectRatio: '<string>',
style: '<string>',
referenceImageUrls: [{}],
referenceImageUrl: '<string>',
trainingPreset: '<string>',
enhancePrompt: true,
webhook: '<string>'
})
};
fetch('https://api.pictory.ai/pictoryapis/v1/aistudio/images', 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.pictory.ai/pictoryapis/v1/aistudio/images",
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([
'prompt' => '<string>',
'model' => '<string>',
'aspectRatio' => '<string>',
'style' => '<string>',
'referenceImageUrls' => [
[
]
],
'referenceImageUrl' => '<string>',
'trainingPreset' => '<string>',
'enhancePrompt' => true,
'webhook' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>",
"Content-Type: <content-type>"
],
]);
$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.pictory.ai/pictoryapis/v1/aistudio/images"
payload := strings.NewReader("{\n \"prompt\": \"<string>\",\n \"model\": \"<string>\",\n \"aspectRatio\": \"<string>\",\n \"style\": \"<string>\",\n \"referenceImageUrls\": [\n {}\n ],\n \"referenceImageUrl\": \"<string>\",\n \"trainingPreset\": \"<string>\",\n \"enhancePrompt\": true,\n \"webhook\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<authorization>")
req.Header.Add("Content-Type", "<content-type>")
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.pictory.ai/pictoryapis/v1/aistudio/images")
.header("Authorization", "<authorization>")
.header("Content-Type", "<content-type>")
.body("{\n \"prompt\": \"<string>\",\n \"model\": \"<string>\",\n \"aspectRatio\": \"<string>\",\n \"style\": \"<string>\",\n \"referenceImageUrls\": [\n {}\n ],\n \"referenceImageUrl\": \"<string>\",\n \"trainingPreset\": \"<string>\",\n \"enhancePrompt\": true,\n \"webhook\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.pictory.ai/pictoryapis/v1/aistudio/images")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
request["Content-Type"] = '<content-type>'
request.body = "{\n \"prompt\": \"<string>\",\n \"model\": \"<string>\",\n \"aspectRatio\": \"<string>\",\n \"style\": \"<string>\",\n \"referenceImageUrls\": [\n {}\n ],\n \"referenceImageUrl\": \"<string>\",\n \"trainingPreset\": \"<string>\",\n \"enhancePrompt\": true,\n \"webhook\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"jobId": "4d82d040-4394-4371-867d-72ae1dd62b6d"
}
}
{
"code": "INVALID_REQUEST_BODY",
"message": "Request body validation failed.",
"fields": [
{
"name": "prompt",
"errors": "prompt is required"
}
]
}
{
"code": "IMAGE_EDITING_NOT_SUPPORTED",
"message": "The selected model 'flux-schnell' does not support image editing with reference images."
}
{
"message": "Unauthorized"
}
{
"message": "Internal Server Error"
}
AI Studio
Generate Image
Generate an AI image from a text prompt using a selection of AI image models
POST
/
pictoryapis
/
v1
/
aistudio
/
images
Generate Image
curl --request POST \
--url https://api.pictory.ai/pictoryapis/v1/aistudio/images \
--header 'Authorization: <authorization>' \
--header 'Content-Type: <content-type>' \
--data '
{
"prompt": "<string>",
"model": "<string>",
"aspectRatio": "<string>",
"style": "<string>",
"referenceImageUrls": [
{}
],
"referenceImageUrl": "<string>",
"trainingPreset": "<string>",
"enhancePrompt": true,
"webhook": "<string>"
}
'import requests
url = "https://api.pictory.ai/pictoryapis/v1/aistudio/images"
payload = {
"prompt": "<string>",
"model": "<string>",
"aspectRatio": "<string>",
"style": "<string>",
"referenceImageUrls": [{}],
"referenceImageUrl": "<string>",
"trainingPreset": "<string>",
"enhancePrompt": True,
"webhook": "<string>"
}
headers = {
"Authorization": "<authorization>",
"Content-Type": "<content-type>"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: '<authorization>', 'Content-Type': '<content-type>'},
body: JSON.stringify({
prompt: '<string>',
model: '<string>',
aspectRatio: '<string>',
style: '<string>',
referenceImageUrls: [{}],
referenceImageUrl: '<string>',
trainingPreset: '<string>',
enhancePrompt: true,
webhook: '<string>'
})
};
fetch('https://api.pictory.ai/pictoryapis/v1/aistudio/images', 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.pictory.ai/pictoryapis/v1/aistudio/images",
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([
'prompt' => '<string>',
'model' => '<string>',
'aspectRatio' => '<string>',
'style' => '<string>',
'referenceImageUrls' => [
[
]
],
'referenceImageUrl' => '<string>',
'trainingPreset' => '<string>',
'enhancePrompt' => true,
'webhook' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Authorization: <authorization>",
"Content-Type: <content-type>"
],
]);
$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.pictory.ai/pictoryapis/v1/aistudio/images"
payload := strings.NewReader("{\n \"prompt\": \"<string>\",\n \"model\": \"<string>\",\n \"aspectRatio\": \"<string>\",\n \"style\": \"<string>\",\n \"referenceImageUrls\": [\n {}\n ],\n \"referenceImageUrl\": \"<string>\",\n \"trainingPreset\": \"<string>\",\n \"enhancePrompt\": true,\n \"webhook\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "<authorization>")
req.Header.Add("Content-Type", "<content-type>")
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.pictory.ai/pictoryapis/v1/aistudio/images")
.header("Authorization", "<authorization>")
.header("Content-Type", "<content-type>")
.body("{\n \"prompt\": \"<string>\",\n \"model\": \"<string>\",\n \"aspectRatio\": \"<string>\",\n \"style\": \"<string>\",\n \"referenceImageUrls\": [\n {}\n ],\n \"referenceImageUrl\": \"<string>\",\n \"trainingPreset\": \"<string>\",\n \"enhancePrompt\": true,\n \"webhook\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.pictory.ai/pictoryapis/v1/aistudio/images")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = '<authorization>'
request["Content-Type"] = '<content-type>'
request.body = "{\n \"prompt\": \"<string>\",\n \"model\": \"<string>\",\n \"aspectRatio\": \"<string>\",\n \"style\": \"<string>\",\n \"referenceImageUrls\": [\n {}\n ],\n \"referenceImageUrl\": \"<string>\",\n \"trainingPreset\": \"<string>\",\n \"enhancePrompt\": true,\n \"webhook\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"data": {
"jobId": "4d82d040-4394-4371-867d-72ae1dd62b6d"
}
}
{
"code": "INVALID_REQUEST_BODY",
"message": "Request body validation failed.",
"fields": [
{
"name": "prompt",
"errors": "prompt is required"
}
]
}
{
"code": "IMAGE_EDITING_NOT_SUPPORTED",
"message": "The selected model 'flux-schnell' does not support image editing with reference images."
}
{
"message": "Unauthorized"
}
{
"message": "Internal Server Error"
}
Overview
The Generate Image API creates an AI-generated image based on a text prompt. You can choose from multiple AI image models, specify an aspect ratio, apply a visual style, and optionally provide up to four reference images to edit or combine. The API returns a job ID that you can use to poll for the result once the image generation is complete.A valid API key is required to use this endpoint. Obtain your API key from the API Access page in your Pictory dashboard.
API Endpoint
POST https://api.pictory.ai/pictoryapis/v1/aistudio/images
Request Headers
string
required
API key for authentication (starts with
pictai_)Authorization: YOUR_API_KEY
string
required
Must be
application/jsonRequest Body
string
required
A text description of the image you want to generate. The prompt must be between 5 and 5,000 characters.Example:
"A serene mountain landscape at sunset with a reflective lake in the foreground"string
The AI model to use for image generation. Each model produces different visual styles and quality levels. Defaults to
seedream3.0 if not specified.Supported models: seedream3.0, flux-schnell, nanobanana-lite2, nanobanana2, nanobanana, nanobanana-pro, nova-canvasModel Capabilities and Pricing:| Model | Supported Aspect Ratios | AI Credits per Image | Reference Images | Aspect Ratio on Edits |
|---|---|---|---|---|
seedream3.0 | 1:1, 16:9, 9:16 | 2 | Up to 4 | Honored |
flux-schnell | 1:1, 16:9, 9:16 | 0.6 | Not supported | - |
nanobanana-lite2 | 1:1, 16:9, 9:16 | 4 | Up to 4 | Honored |
nanobanana2 | 1:1, 16:9, 9:16 | 8 | Up to 4 | Honored |
nanobanana | 1:1, 16:9, 9:16 | 4 | Up to 4 | Follows the reference |
nanobanana-pro | 1:1, 16:9, 9:16 | 14 | Up to 4 | Honored |
nova-canvas | 1:1, 16:9, 9:16 | 4 | 1 | Follows the reference |
nanobanana-lite2 cannot edit images itself. A request with reference images on nanobanana-lite2 is served by nanobanana2 and billed at the nanobanana-lite2 rate. Where “Aspect Ratio on Edits” says “Follows the reference”, the output keeps the reference image’s aspect ratio and the aspectRatio field only applies to generation without references.string
The aspect ratio for the generated image. Every model accepts
1:1, 16:9, and 9:16. Defaults to 1:1. With reference images, the ratio is only honored on the models marked so in the table above; the others keep the reference image’s ratio.string
The visual style to apply to the generated image. Defaults to
photorealistic.Supported values: photorealistic, artistic, cartoon, minimalist, vintage, futuristicarray
An optional array of 1 to 4 reference image URLs. The model edits, combines, or restyles the referenced images according to the prompt. Each URL must be a valid, publicly accessible URI. Sending more references than the model allows returns a
400 validation error; sending references to flux-schnell returns a 400 with the code IMAGE_EDITING_NOT_SUPPORTED.This parameter cannot be used together with
referenceImageUrl.string
A single reference image URL. Kept for existing integrations; it behaves exactly like a one-element
referenceImageUrls. New integrations should use referenceImageUrls.string
Steer the generation toward a training-content use case. The preset is a fixed directive applied during prompt enhancement, so sending it always turns enhancement on, even when
enhancePrompt is false. Supported values: sales-training, product-training, soft-skills-training.boolean
Whether Pictory rewrites your prompt with an AI enhancer before generation, adding cinematic and compositional detail. Off by default: your prompt goes to the model exactly as written. Set to
true to enhance it. Sending a trainingPreset always turns enhancement on. Sending a style also turns it on, unless you set enhancePrompt: false. When enhancement runs, the completed job returns the rewritten text as enhancedPrompt.string
An optional webhook URL that will receive a notification when the image generation job completes. The URL must be a valid URI.
Response
Success Response (200)
boolean
true when the job has been created successfullyobject
string
The unique identifier (UUID) of the image generation job. Use this ID to poll for the result using the Get Image Generation Job endpoint.
Response Examples
{
"success": true,
"data": {
"jobId": "4d82d040-4394-4371-867d-72ae1dd62b6d"
}
}
{
"code": "INVALID_REQUEST_BODY",
"message": "Request body validation failed.",
"fields": [
{
"name": "prompt",
"errors": "prompt is required"
}
]
}
{
"code": "IMAGE_EDITING_NOT_SUPPORTED",
"message": "The selected model 'flux-schnell' does not support image editing with reference images."
}
{
"message": "Unauthorized"
}
{
"message": "Internal Server Error"
}
Status Codes
| Status Code | Description |
|---|---|
| 200 | Job created successfully. Use the returned jobId to poll for the result. |
| 400 | Invalid request body. Check the fields array for specific validation errors. Also returned with the code IMAGE_EDITING_NOT_SUPPORTED when reference images are sent to a model that cannot edit. |
| 401 | Unauthorized. The API key in the Authorization header is missing or invalid. |
| 500 | Internal server error. Retry the request after a brief delay. |
Code Examples
Replace
YOUR_API_KEY with your actual API key from the API Access page.curl --request POST \
--url 'https://api.pictory.ai/pictoryapis/v1/aistudio/images' \
--header 'Authorization: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"prompt": "A serene mountain landscape at sunset with a reflective lake in the foreground",
"model": "seedream3.0",
"aspectRatio": "16:9",
"style": "photorealistic"
}'
import requests
url = "https://api.pictory.ai/pictoryapis/v1/aistudio/images"
headers = {
"Authorization": "YOUR_API_KEY",
"Content-Type": "application/json"
}
payload = {
"prompt": "A serene mountain landscape at sunset with a reflective lake in the foreground",
"model": "seedream3.0",
"aspectRatio": "16:9",
"style": "photorealistic"
}
response = requests.post(url, json=payload, headers=headers)
data = response.json()
if data.get("success"):
job_id = data["data"]["jobId"]
print(f"Image generation job created: {job_id}")
else:
print(f"Error: {data}")
const url = 'https://api.pictory.ai/pictoryapis/v1/aistudio/images';
const response = await fetch(url, {
method: 'POST',
headers: {
'Authorization': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
prompt: 'A serene mountain landscape at sunset with a reflective lake in the foreground',
model: 'seedream3.0',
aspectRatio: '16:9',
style: 'photorealistic'
})
});
const data = await response.json();
if (data.success) {
console.log(`Image generation job created: ${data.data.jobId}`);
} else {
console.log('Error:', data);
}
<?php
$url = "https://api.pictory.ai/pictoryapis/v1/aistudio/images";
$payload = json_encode([
"prompt" => "A serene mountain landscape at sunset with a reflective lake in the foreground",
"model" => "seedream3.0",
"aspectRatio" => "16:9",
"style" => "photorealistic"
]);
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: YOUR_API_KEY',
'Content-Type: application/json'
]);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
if ($data['success']) {
echo "Image generation job created: " . $data['data']['jobId'] . "\n";
} else {
echo "Error: " . json_encode($data) . "\n";
}
?>
package main
import (
"bytes"
"encoding/json"
"fmt"
"io"
"net/http"
)
func main() {
url := "https://api.pictory.ai/pictoryapis/v1/aistudio/images"
payload := map[string]string{
"prompt": "A serene mountain landscape at sunset with a reflective lake in the foreground",
"model": "seedream3.0",
"aspectRatio": "16:9",
"style": "photorealistic",
}
jsonPayload, _ := json.Marshal(payload)
req, _ := http.NewRequest("POST", url, bytes.NewBuffer(jsonPayload))
req.Header.Set("Authorization", "YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
fmt.Println("Error:", err)
return
}
defer resp.Body.Close()
body, _ := io.ReadAll(resp.Body)
var data map[string]interface{}
json.Unmarshal(body, &data)
if success, ok := data["success"].(bool); ok && success {
jobData := data["data"].(map[string]interface{})
fmt.Printf("Image generation job created: %s\n", jobData["jobId"])
} else {
fmt.Println("Error:", string(body))
}
}
Next Steps
After receiving thejobId, poll for the image generation result using the Get Image Generation Job endpoint. Use a polling interval of 10–30 seconds to check the job status.Was this page helpful?
