Image Generation Basics
Learn how to generate images with xRouter’s AI image generation API.
Prerequisites
Before you start generating images, you’ll need:
- USDC on Base: USDC on Base Mainnet
- Private Key: From a wallet containing USDC
- No ETH Required: x402 payments are gasless for clients
Getting USDC on Base Mainnet
- Purchase USDC on exchanges (Coinbase, Binance, etc.)
- Bridge USDC from Ethereum to Base using bridge.base.org
Quick Start
Step 1: Install Dependencies
npm install x402-fetch viemStep 2: Set Up Environment Variables
Create a .env file:
PRIVATE_KEY=0x...
NETWORK_ID=baseStep 3: Initialize Payment Client
import { wrapFetchWithPayment } from 'x402-fetch';
import { privateKeyToAccount } from 'viem/accounts';
// Create account from private key
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
// Wrap fetch with x402 payment handling
const fetchWithPayment = wrapFetchWithPayment(fetch, account);Step 4: Generate Your First Image
async function generateFirstImage() {
const response = await fetchWithPayment('https://api.x-router.ai/v1/images/generate', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
prompt: 'a cute cat sitting on a windowsill, photorealistic',
width: 512,
height: 512,
}),
});
const data = await response.json();
console.log('Image generated successfully!');
console.log('URL:', data.images[0].url);
console.log('UUID:', data.images[0].uuid);
}
generateFirstImage();Step 5: View Your Image
The API returns a CDN URL that you can:
- Open in your browser
- Use in an
<img>tag - Download and save locally
- Share publicly
// Display in HTML
const imageUrl = data.images[0].url;
document.getElementById('myImage').src = imageUrl;
// Download locally
const response = await fetch(imageUrl);
const blob = await response.blob();
// Save blob to fileUnderstanding the Basics
Prompts
The prompt is a text description of what you want to generate. Good prompts are:
Specific and Descriptive:
❌ "a dog"
✅ "a golden retriever puppy sitting in a meadow, sunny day, professional photography"Include Style Keywords:
❌ "a city street"
✅ "a city street at night, cyberpunk style, neon lights, rain-soaked pavement, cinematic"Specify Quality:
❌ "a mountain"
✅ "a snow-capped mountain at sunrise, highly detailed, 8k resolution, dramatic lighting"Models
Different models excel at different tasks. The default model is flux-schnell:
// Use default model (flux-schnell)
{
prompt: "your prompt"
}
// Specify a different model
{
prompt: "your prompt",
model: "sdxl-realvis-v4" // Better for photorealism
}Quick Model Guide:
flux-schnell: Fast, good quality, great for testingflux-dev: Professional photorealismsdxl-realvis-v4: Best SDXL photorealismsd15-dreamshaper-v8: Artistic and creativesd15-counterfeit-v3: Anime and mangapremium-midjourney-v7: Cinematic quality (premium)flux-hunyuan-3: Best for text rendering
See the Model Selection Guide for detailed recommendations.
Resolutions
Common resolutions and their uses:
512×512 - Quick tests, social media thumbnails
{ width: 512, height: 512 }1024×1024 - Standard, most use cases
{ width: 1024, height: 1024 }2048×2048 - High quality, print-ready
{ width: 2048, height: 2048 }Important: Width and height must be divisible by 64.
Aspect Ratios
Generate images in different orientations:
Square (1:1):
{ width: 1024, height: 1024 }Portrait (3:4):
{ width: 768, height: 1024 }Landscape (16:9):
{ width: 1152, height: 640 }Common Use Cases
Profile Pictures
Generate portrait-oriented images for avatars and profile photos:
const response = await fetchWithPayment('https://api.x-router.ai/v1/images/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
prompt: 'professional headshot of a business person, studio lighting, neutral background',
model: 'sdxl-realvis-v4',
width: 768,
height: 1024,
}),
});Social Media Graphics
Create square images optimized for social media:
const response = await fetchWithPayment('https://api.x-router.ai/v1/images/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
prompt: 'motivational quote design, modern minimalist style, vibrant colors',
model: 'sdxl-dreamshaper',
width: 1024,
height: 1024,
}),
});Wallpapers
Generate wide images for desktop backgrounds:
const response = await fetchWithPayment('https://api.x-router.ai/v1/images/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
prompt: 'epic fantasy landscape, mountains and valleys, magical atmosphere, wide angle',
model: 'flux-dev',
width: 1920,
height: 1088,
}),
});Product Mockups
Create realistic product images:
const response = await fetchWithPayment('https://api.x-router.ai/v1/images/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
prompt: 'modern smartphone on a wooden desk, professional product photography, soft lighting',
model: 'sdxl-realvis-v4',
width: 1024,
height: 1024,
}),
});Concept Art
Generate creative concepts and illustrations:
const response = await fetchWithPayment('https://api.x-router.ai/v1/images/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
prompt: 'futuristic sci-fi city, flying vehicles, neon signs, concept art style',
model: 'sdxl-dreamshaper',
width: 1280,
height: 768,
}),
});Anime and Manga
Create anime-style illustrations:
const response = await fetchWithPayment('https://api.x-router.ai/v1/images/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
prompt: 'anime girl with blue hair, school uniform, cherry blossoms, spring day',
model: 'sd15-counterfeit-v3',
width: 768,
height: 1024,
}),
});Complete Example Application
Here’s a full working example:
import 'dotenv/config';
import { wrapFetchWithPayment } from 'x402-fetch';
import { privateKeyToAccount } from 'viem/accounts';
const API_URL = 'https://api.x-router.ai';
async function main() {
// Set up authentication
const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`);
const fetchWithPayment = wrapFetchWithPayment(fetch, account);
console.log('Wallet Address:', account.address);
console.log('');
// Step 1: Get cost estimate
console.log('Estimating cost...');
const estimateRes = await fetch(`${API_URL}/v1/images/estimate`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
model: 'flux-schnell',
width: 1024,
height: 1024,
numberResults: 1,
}),
});
const estimate = await estimateRes.json();
console.log(` Estimated cost: $${estimate.estimatedCost.usd} USDC`);
console.log('');
// Step 2: Generate image
console.log('Generating image...');
const response = await fetchWithPayment(`${API_URL}/v1/images/generate`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
prompt: 'a serene mountain landscape at sunset, highly detailed, photorealistic',
model: 'flux-schnell',
width: 1024,
height: 1024,
numberResults: 1,
}),
});
if (!response.ok) {
const error = await response.text();
throw new Error(`Generation failed: ${error}`);
}
const data = await response.json();
// Step 3: Display results
console.log('Image generated successfully!');
console.log('');
console.log('Image URL:', data.images[0].url);
console.log('UUID:', data.images[0].uuid);
console.log('Model:', data.model);
console.log('');
console.log('Open the URL in your browser to view the image!');
}
main().catch((error) => {
console.error('Error:', error.message);
process.exit(1);
});Save this as generate-image.ts and run:
npx tsx generate-image.tsChecking Costs Before Generation
Always estimate costs first to avoid surprises:
async function estimateAndGenerate(prompt: string, width: number, height: number) {
// Get estimate
const estimateRes = await fetch('https://api.x-router.ai/v1/images/estimate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ model: 'flux-schnell', width, height, numberResults: 1 }),
});
const estimate = await estimateRes.json();
console.log(`Cost: $${estimate.estimatedCost.usd} USDC`);
// Ask for confirmation (in your actual app)
const confirmed = true; // Your confirmation logic
if (confirmed) {
const response = await fetchWithPayment('https://api.x-router.ai/v1/images/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ prompt, width, height }),
});
return await response.json();
}
}Troubleshooting
Validation Errors
“Width and height must be divisible by 64”
❌ { width: 1000, height: 1000 }
✅ { width: 1024, height: 1024 }“Dimensions outside valid range”
❌ { width: 100, height: 100 } // Too small
❌ { width: 4096, height: 4096 } // Too large
✅ { width: 512, height: 512 } // Valid
✅ { width: 2048, height: 2048 } // Maximum“Invalid model ID”
❌ { model: 'unknown-model' }
✅ { model: 'flux-schnell' }Check available models for valid model IDs.
Payment Issues
Insufficient USDC Balance:
- Check your wallet balance on Base
- Ensure you have sufficient USDC on Base Mainnet
Payment Amount Exceeds Maximum:
- The
x402-fetchlibrary has a default spending limit (~$0.10) - High-resolution images and premium models cost more
- Increase the limit:
wrapFetchWithPayment(fetch, account, { maxAmountPerRequest: 5.0 }) - See Spending Limits for details
Payment Timeout:
- Check network connectivity
- Verify the x402 facilitator is operational
- Try again after a moment
Quality Problems
Image doesn’t match prompt:
- Make your prompt more specific
- Try a different model
- Increase guidance parameter (if supported)
Blurry or low quality:
- Increase resolution (e.g., 1024×1024 instead of 512×512)
- Use a model better suited for your style
- Add quality keywords: “highly detailed”, “professional”, “8k”
Unexpected elements:
- Use negative prompts to exclude unwanted content
- Be more specific in your main prompt
- Try a different random seed
Best Practices Summary
- Start small: Test prompts at 512×512 before going to higher resolutions
- Use estimates: Always check costs before generating
- Be specific: Detailed prompts produce better results
- Choose the right model: Different models excel at different styles
- Iterate: Generate variations and refine your prompts
- Save UUIDs: Store image UUIDs for future reference
- Handle errors: Always implement proper error handling
Next Steps
Now that you understand the basics, explore more advanced topics:
- Quality Optimization - Learn techniques to improve image quality
- Model Selection - Choose the best model for your use case
- API Reference - Complete API documentation
Ready to generate amazing images! 🎨