Documentation Index
Fetch the complete documentation index at: https://docs.nano-gpt.com/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The NanoGPT API provides image generation through the OpenAI-compatible endpoint. This guide covers text-to-image and image-to-image flows, response formats, and best practices.
OpenAI-Compatible Endpoint (v1/images/generations)
This endpoint follows the OpenAI specification for image generation and returns a list of base64-encoded images by default (or hosted URLs when response_format: "url").
Basic Image Generation
curl https://nano-gpt.com/v1/images/generations \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "hidream",
"prompt": "A sunset over a mountain range",
"n": 1,
"size": "1024x1024"
}'
By default, responses include base64 strings. Ask for hosted URLs instead:
{
"response_format": "url"
}
Note on response_format: “url”
The returned data[i].url is a time-limited, signed download URL (presigned URL) to the generated image.
It will expire after a short period (currently ~1 hour). If you need long-term access, download the image and store it yourself.
- Output:
data will usually contain { url: "https://..." } entries instead of b64_json (each data[i] is one or the other, never both).
- Fallback: if URL generation (upload/presign) fails, the API may return
b64_json even when you requested response_format: "url".
- Inputs:
imageDataUrl accepts data URLs; download and convert remote images before sending.
- Retention: the returned
data[i].url is a signed, expiring URL (~1 hour). Generated files are kept for 24 hours, then permanently deleted. Download and store elsewhere if you need longer retention.
Example response (response_format: “url”)
{
"created": 123,
"data": [
{ "url": "https://...signed-url..." }
],
"cost": 123,
"paymentSource": "<string>",
"remainingBalance": 123
}
Example response (response_format: “b64_json”)
{
"created": 123,
"data": [
{ "b64_json": "<base64-encoded-image-bytes>" }
],
"cost": 123,
"paymentSource": "<string>",
"remainingBalance": 123
}
Downloading the image
If you requested response_format: “url”, download the image by performing a normal HTTP GET to data[i].url.
Because the URL is signed and expiring, you should download it soon after generation.
Image-to-Image with OpenAI Endpoint
The OpenAI-compatible endpoint also supports img2img generation using the imageDataUrl parameter. Here are the different ways to provide input images:
Uploads sent via the API must be 4 MB or smaller. Compress or resize larger files before converting to a data URL.
Method 1: Upload from Local File
import requests
import base64
API_KEY = "YOUR_API_KEY"
# Read and encode your input image
with open("input_image.jpg", "rb") as image_file:
encoded_image = base64.b64encode(image_file.read()).decode('utf-8')
image_data_url = f"data:image/jpeg;base64,{encoded_image}"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
response = requests.post(
"https://nano-gpt.com/v1/images/generations",
headers=headers,
json={
"model": "flux-kontext",
"prompt": "Transform this image into a watercolor painting",
"n": 1,
"size": "1024x1024",
"imageDataUrl": image_data_url
}
)
result = response.json()
# The response includes base64-encoded images in result["data"]
Method 2: Upload from Image URL
import requests
import base64
from urllib.request import urlopen
API_KEY = "YOUR_API_KEY"
# Download and encode image from URL
image_url = "https://example.com/your-image.jpg"
with urlopen(image_url) as response:
image_data = response.read()
encoded_image = base64.b64encode(image_data).decode('utf-8')
# Detect image type from URL or response headers
image_type = "jpeg" # or detect from URL/headers
image_data_url = f"data:image/{image_type};base64,{encoded_image}"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
response = requests.post(
"https://nano-gpt.com/v1/images/generations",
headers=headers,
json={
"model": "flux-kontext",
"prompt": "Transform this image into a watercolor painting",
"n": 1,
"size": "1024x1024",
"imageDataUrl": image_data_url
}
)
result = response.json()
Method 3: Multiple Images (for supported models)
Some models like gpt-4o-image, flux-kontext, and gpt-image-1 support multiple input images:
import requests
import base64
API_KEY = "YOUR_API_KEY"
def image_to_data_url(image_path):
"""Convert image file to base64 data URL"""
with open(image_path, "rb") as f:
encoded = base64.b64encode(f.read()).decode('utf-8')
ext = image_path.lower().split('.')[-1]
mime_type = "jpeg" if ext == "jpg" else ext
return f"data:image/{mime_type};base64,{encoded}"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
# Prepare multiple images
image_data_urls = [
image_to_data_url("image1.jpg"),
image_to_data_url("image2.png"),
image_to_data_url("image3.jpg")
]
response = requests.post(
"https://nano-gpt.com/v1/images/generations",
headers=headers,
json={
"model": "gpt-4o-image",
"prompt": "Combine these images into a creative collage",
"n": 1,
"size": "1024x1024",
"imageDataUrls": image_data_urls # Note: plural form for multiple images
}
)
result = response.json()
Supported Image-to-Image Models
The following models support image input via the OpenAI endpoint:
Single Image Input:
flux-dev-image-to-image - Image-to-image only
ghiblify - Transform images to Studio Ghibli style
gemini-flash-edit - Edit images with prompts
hidream-edit - Advanced image editing
bagel - Both text-to-image and image-to-image
SDXL-ArliMix-v1 - Artistic transformations
Upscaler - Upscale images to higher resolution
Multiple Image Input:
flux-kontext - Advanced context-aware generation
flux-kontext/dev - Development version (image-to-image only)
gpt-4o-image - GPT-4 powered image generation
gpt-image-1 - Advanced multi-image processing
Special Cases:
flux-lora/inpainting - Requires both imageDataUrl (base image) and maskDataUrl (mask)
All images must be provided as base64-encoded data URLs:
data:image/[format];base64,[base64-encoded-data]
Supported formats:
image/jpeg or image/jpg
image/png
image/webp
image/gif (first frame only)
Additional Parameters for Image-to-Image
When using image-to-image models, you can include these additional parameters:
{
"model": "flux-kontext",
"prompt": "Transform to cyberpunk style",
"imageDataUrl": "data:image/jpeg;base64,...",
"size": "1024x1024",
"n": 1,
// Optional parameters (model-specific)
"strength": 0.8, // How much to transform (0.0-1.0)
"guidance_scale": 7.5, // Prompt adherence
"num_inference_steps": 30, // Quality vs speed
"seed": 42, // For reproducible results
"kontext_max_mode": true // Enhanced context (flux-kontext only)
}
Best Practices
-
Prompt Engineering
- Be specific and detailed in your prompts
- Include style references when needed
- Use the negative prompt to avoid unwanted elements
- For img2img, describe the changes you want relative to the input image
-
Image Quality
- Higher resolution settings produce better quality but take longer
- More steps generally mean better quality but slower generation
- Adjust the guidance scale based on how closely you want to follow the prompt
- For img2img, ensure your input image has good quality for best results
-
Cost Optimization
- Start with lower resolution for testing
- Use fewer steps during development
- Generate one image at a time unless multiple variations are needed
- Compress input images appropriately to reduce upload size
Error Handling
The API may return various error codes:
- 400: Bad Request (invalid parameters)
- 401: Unauthorized (invalid API key)
- 429: Too Many Requests (rate limit exceeded)
- 500: Internal Server Error
Always implement proper error handling in your applications:
try:
result = generate_image(prompt)
except requests.exceptions.RequestException as e:
if e.response:
if e.response.status_code == 401:
print("Invalid API key. Please check your credentials.")
elif e.response.status_code == 429:
print("Rate limit exceeded. Please wait before trying again.")
else:
print(f"API Error: {e.response.status_code}")
else:
print(f"Network Error: {str(e)}")