# cURL Examples Source: https://docs.firemoon.studio/api-reference/examples/curl Command-line examples for testing the Firemoon Studio API ## Basic Image Generation ### FLUX/dev - Simple Generation ```bash theme={null} curl -X POST https://firemoon.studio/api/v1/flux/dev \ -H "Authorization: Bearer your_api_key_here" \ -H "Content-Type: application/json" \ -d '{ "prompt": "A beautiful sunset over mountains" }' ``` ### FLUX/dev - Advanced Parameters ```bash theme={null} curl -X POST https://firemoon.studio/api/v1/flux/dev \ -H "Authorization: Bearer your_api_key_here" \ -H "Content-Type: application/json" \ -d '{ "prompt": "A futuristic city with flying cars, cyberpunk style, highly detailed", "num_images": 2, "image_size": "landscape_16_9", "guidance_scale": 7.5, "num_inference_steps": 35, "seed": 12345 }' ``` ## Video Generation ### Kling - Basic Video ```bash theme={null} curl -X POST https://firemoon.studio/api/v1/kling/kling-2-1-master \ -H "Authorization: Bearer your_api_key_here" \ -H "Content-Type: application/json" \ -d '{ "prompt": "A butterfly emerging from its chrysalis and flying away", "duration": "5", "aspect_ratio": "16:9" }' ``` ### Kling - Marketing Video ```bash theme={null} curl -X POST https://firemoon.studio/api/v1/kling/kling-2-1-master \ -H "Authorization: Bearer your_api_key_here" \ -H "Content-Type: application/json" \ -d '{ "prompt": "A sleek electric car driving through a futuristic city at sunset, smooth camera movement following the vehicle", "duration": "10", "aspect_ratio": "16:9", "seed": 42 }' ``` ## Character Editing ### Ideogram - Character Edit ```bash theme={null} curl -X POST https://firemoon.studio/api/v1/ideogram/v3-character-edit \ -H "Authorization: Bearer your_api_key_here" \ -H "Content-Type: application/json" \ -d '{ "prompt": "Change the character to wear a blue jacket and sunglasses", "image_url": "https://example.com/character.jpg", "style": "realistic", "magic_prompt_option": "auto" }' ``` ## API Information ### Get API Version ```bash theme={null} curl https://firemoon.studio/api/v1 ``` ### List Providers ```bash theme={null} curl https://firemoon.studio/api/v1/providers ``` ### List Models for Provider ```bash theme={null} # FLUX models curl https://firemoon.studio/api/v1/providers/flux/models # Ideogram models curl https://firemoon.studio/api/v1/providers/ideogram/models # Kling models curl https://firemoon.studio/api/v1/providers/kling/models ``` ### Get Model Information ```bash theme={null} # FLUX/dev info curl https://firemoon.studio/api/v1/flux/dev # Kling video info curl https://firemoon.studio/api/v1/kling/kling-2-1-master ``` ## Testing Scripts ### Batch Image Generation ```bash theme={null} #!/bin/bash # Set your API key API_KEY="your_api_key_here" BASE_URL="https://firemoon.studio/api/v1" # Array of prompts prompts=( "A serene mountain landscape at sunset" "A futuristic city skyline with neon lights" "A peaceful lake surrounded by autumn trees" "A rocket launching into space" "A butterfly resting on a flower petal" ) echo "Generating images..." for i in "${!prompts[@]}"; do prompt="${prompts[$i]}" echo "Generating image $((i+1))/${#prompts[@]}: $prompt" curl -X POST "$BASE_URL/flux/dev" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d "{\"prompt\": \"$prompt\", \"num_images\": 1}" \ --silent | jq '.images[0].url' 2>/dev/null || echo "Failed to generate" # Small delay to be respectful sleep 1 done echo "Batch generation complete!" ``` ### Test All Providers ```bash theme={null} #!/bin/bash API_KEY="your_api_key_here" BASE_URL="https://firemoon.studio/api/v1" echo "Testing FLUX image generation..." curl -X POST "$BASE_URL/flux/dev" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{"prompt": "A test image", "num_images": 1}' \ -w "\nStatus: %{http_code}\nTime: %{time_total}s\n" echo -e "\nTesting Kling video generation..." curl -X POST "$BASE_URL/kling/kling-2-1-master" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{"prompt": "A test video", "duration": "5"}' \ -w "\nStatus: %{http_code}\nTime: %{time_total}s\n" echo -e "\nTesting API info..." curl "$BASE_URL" -w "\nStatus: %{http_code}\n" echo -e "\nTesting providers list..." curl "$BASE_URL/providers" -w "\nStatus: %{http_code}\n" ``` ### Rate Limit Testing ```bash theme={null} #!/bin/bash API_KEY="your_api_key_here" BASE_URL="https://firemoon.studio/api/v1" echo "Testing rate limits..." for i in {1..10}; do echo "Request $i:" curl -X POST "$BASE_URL/flux/dev" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{"prompt": "Rate limit test", "num_images": 1}' \ --silent \ -w "Status: %{http_code}, Remaining: %{header:X-RateLimit-Remaining}\n" \ -o /dev/null sleep 0.5 # Small delay between requests done ``` ### Error Testing ```bash theme={null} #!/bin/bash API_KEY="your_api_key_here" BASE_URL="https://firemoon.studio/api/v1" echo "Testing error responses..." # Invalid API key echo "1. Invalid API key:" curl -X POST "$BASE_URL/flux/dev" \ -H "Authorization: Bearer invalid_key" \ -H "Content-Type: application/json" \ -d '{"prompt": "Test"}' \ -w "\nStatus: %{http_code}\n" # Missing prompt echo -e "\n2. Missing prompt:" curl -X POST "$BASE_URL/flux/dev" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{}' \ -w "\nStatus: %{http_code}\n" # Invalid provider echo -e "\n3. Invalid provider:" curl -X POST "$BASE_URL/invalid-provider/model" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{"prompt": "Test"}' \ -w "\nStatus: %{http_code}\n" # Invalid model echo -e "\n4. Invalid model:" curl -X POST "$BASE_URL/flux/invalid-model" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{"prompt": "Test"}' \ -w "\nStatus: %{http_code}\n" ``` ## Response Parsing ### Extract Image URLs ```bash theme={null} # Generate image and extract URL curl -X POST https://firemoon.studio/api/v1/flux/dev \ -H "Authorization: Bearer your_api_key_here" \ -H "Content-Type: application/json" \ -d '{"prompt": "A sunset"}' \ | jq -r '.images[0].url' ``` ### Pretty Print Response ```bash theme={null} # Pretty print JSON response curl -X POST https://firemoon.studio/api/v1/flux/dev \ -H "Authorization: Bearer your_api_key_here" \ -H "Content-Type: application/json" \ -d '{"prompt": "A sunset"}' \ | jq '.' ``` ## Automation Scripts ### Generate and Download Images ```bash theme={null} #!/bin/bash API_KEY="your_api_key_here" BASE_URL="https://firemoon.studio/api/v1" PROMPT="A beautiful landscape" OUTPUT_DIR="./generated_images" mkdir -p "$OUTPUT_DIR" echo "Generating image..." response=$(curl -s -X POST "$BASE_URL/flux/dev" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d "{\"prompt\": \"$PROMPT\", \"num_images\": 1}") image_url=$(echo "$response" | jq -r '.images[0].url') if [ "$image_url" != "null" ] && [ -n "$image_url" ]; then echo "Downloading image from: $image_url" filename="$OUTPUT_DIR/$(basename "$image_url")" curl -s "$image_url" -o "$filename" echo "Saved to: $filename" else echo "Failed to generate image" echo "Response: $response" fi ``` ### Monitor API Usage ```bash theme={null} #!/bin/bash API_KEY="your_api_key_here" BASE_URL="https://firemoon.studio/api/v1" LOG_FILE="api_usage.log" echo "$(date): Starting API usage monitoring" >> "$LOG_FILE" while true; do # Make a test request to check rate limits response=$(curl -s -w "%{http_code}" -X POST "$BASE_URL/flux/dev" \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{"prompt": "Usage monitoring", "num_images": 1}' \ -D /tmp/headers.txt) status_code=$(tail -n1 /tmp/headers.txt | cut -d' ' -f2) remaining=$(grep -i "X-RateLimit-Remaining" /tmp/headers.txt | cut -d' ' -f2) echo "$(date): Status $status_code, Remaining $remaining" >> "$LOG_FILE" if [ "$remaining" -lt 10 ]; then echo "$(date): WARNING: Only $remaining requests remaining!" >> "$LOG_FILE" fi # Check every 30 seconds sleep 30 done ``` These cURL examples are perfect for testing the API, debugging issues, and integrating into scripts or automation workflows. # JavaScript Examples Source: https://docs.firemoon.studio/api-reference/examples/javascript Complete JavaScript and TypeScript examples for the Firemoon Studio API ## Setup ### Installing Dependencies ```bash theme={null} npm install node-fetch # For Node.js < 18 # or npm install undici # Modern alternative ``` ### Environment Setup ```javascript theme={null} // .env FIREMOON_API_KEY=your_api_key_here ``` ```javascript theme={null} // Load environment variables require('dotenv').config(); const API_KEY = process.env.FIREMOON_API_KEY; const BASE_URL = 'https://firemoon.studio/api/v1'; ``` ## Basic Image Generation ```javascript theme={null} async function generateImage(prompt, options = {}) { const response = await fetch(`${BASE_URL}/flux/dev`, { method: 'POST', headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt, num_images: options.numImages || 1, image_size: options.size || 'landscape_4_3', guidance_scale: options.guidance || 3.5, ...options }) }); if (!response.ok) { const error = await response.json(); throw new Error(`API Error: ${error.message}`); } return await response.json(); } // Usage try { const result = await generateImage('A beautiful sunset over mountains'); console.log('Generated image:', result.images[0].url); } catch (error) { console.error('Error:', error.message); } ``` ## Video Generation ```javascript theme={null} async function generateVideo(prompt, options = {}) { const response = await fetch(`${BASE_URL}/kling/kling-2-1-master`, { method: 'POST', headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt, duration: options.duration || '5', aspect_ratio: options.aspectRatio || '16:9', ...options }) }); if (!response.ok) { const error = await response.json(); throw new Error(`API Error: ${error.message}`); } return await response.json(); } // Usage const videoResult = await generateVideo( 'A butterfly emerging from its chrysalis', { duration: '10' } ); console.log('Generated video:', videoResult.videos[0].url); ``` ## Character Editing with Ideogram ```javascript theme={null} async function editCharacter(prompt, imageUrl, options = {}) { const response = await fetch(`${BASE_URL}/ideogram/v3-character-edit`, { method: 'POST', headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt, image_url: imageUrl, style: options.style || 'realistic', magic_prompt_option: options.magicPrompt || 'auto', ...options }) }); if (!response.ok) { const error = await response.json(); throw new Error(`API Error: ${error.message}`); } return await response.json(); } // Usage const editResult = await editCharacter( 'Change the character to wear a red jacket', 'https://example.com/character.jpg' ); console.log('Edited image:', editResult.images[0].url); ``` ## Advanced Client Class ```javascript theme={null} class FiremoonStudio { constructor(apiKey, baseUrl = 'https://firemoon.studio/api/v1') { this.apiKey = apiKey; this.baseUrl = baseUrl; } async request(endpoint, params) { const response = await fetch(`${this.baseUrl}${endpoint}`, { method: 'POST', headers: { 'Authorization': `Bearer ${this.apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify(params) }); if (!response.ok) { const error = await response.json(); throw new Error(`API Error: ${error.message}`); } return await response.json(); } // Image generation methods async generateImage(provider, model, params) { return this.request(`/${provider}/${model}`, params); } // Convenience methods async fluxDev(prompt, options = {}) { return this.generateImage('flux', 'dev', { prompt, num_images: 1, image_size: 'landscape_4_3', guidance_scale: 3.5, ...options }); } async klingVideo(prompt, options = {}) { return this.generateImage('kling', 'kling-2-1-master', { prompt, duration: '5', aspect_ratio: '16:9', ...options }); } async ideogramEdit(prompt, imageUrl, options = {}) { return this.generateImage('ideogram', 'v3-character-edit', { prompt, image_url: imageUrl, style: 'realistic', ...options }); } } // Usage const client = new FiremoonStudio(process.env.FIREMOON_API_KEY); // Generate multiple images const images = await client.fluxDev('A futuristic city', { num_images: 3 }); images.images.forEach((img, i) => { console.log(`Image ${i + 1}:`, img.url); }); // Generate video const video = await client.klingVideo('A rocket launch'); console.log('Video:', video.videos[0].url); ``` ## Error Handling and Retries ```javascript theme={null} class FiremoonAPIError extends Error { constructor(message, status, details) { super(message); this.name = 'FiremoonAPIError'; this.status = status; this.details = details; } } async function requestWithRetry(endpoint, params, maxRetries = 3) { let lastError; for (let attempt = 1; attempt <= maxRetries; attempt++) { try { const response = await fetch(`${BASE_URL}${endpoint}`, { method: 'POST', headers: { 'Authorization': `Bearer ${API_KEY}`, 'Content-Type': 'application/json' }, body: JSON.stringify(params) }); if (response.status === 429) { // Rate limited - wait and retry const resetTime = response.headers.get('X-RateLimit-Reset'); const waitTime = Math.min(1000 * Math.pow(2, attempt), 30000); console.log(`Rate limited. Waiting ${waitTime}ms before retry ${attempt}/${maxRetries}`); await new Promise(resolve => setTimeout(resolve, waitTime)); continue; } if (!response.ok) { const error = await response.json(); throw new FiremoonAPIError(error.message, response.status, error); } return await response.json(); } catch (error) { lastError = error; // Don't retry on client errors (4xx except 429) if (error.status >= 400 && error.status < 500 && error.status !== 429) { break; } // Don't retry on last attempt if (attempt === maxRetries) { break; } console.log(`Attempt ${attempt} failed, retrying...`); } } throw lastError; } // Usage with error handling async function safeGenerateImage(prompt) { try { return await requestWithRetry('/flux/dev', { prompt }); } catch (error) { if (error instanceof FiremoonAPIError) { switch (error.status) { case 400: console.error('Invalid request:', error.details); break; case 401: console.error('Invalid API key'); break; case 403: console.error('Access denied to this provider'); break; default: console.error('API error:', error.message); } } else { console.error('Network error:', error.message); } throw error; } } ``` ## Batch Processing ```javascript theme={null} async function generateBatch(prompts, options = {}) { const batchSize = options.batchSize || 3; // Process in batches to avoid rate limits const results = []; const errors = []; for (let i = 0; i < prompts.length; i += batchSize) { const batch = prompts.slice(i, i + batchSize); const batchPromises = batch.map(async (prompt, index) => { try { const result = await requestWithRetry('/flux/dev', { prompt, num_images: 1, ...options }); return { success: true, prompt, result, batchIndex: i + index }; } catch (error) { errors.push({ prompt, error, batchIndex: i + index }); return { success: false, prompt, error, batchIndex: i + index }; } }); const batchResults = await Promise.all(batchPromises); results.push(...batchResults); // Small delay between batches to be respectful if (i + batchSize < prompts.length) { await new Promise(resolve => setTimeout(resolve, 1000)); } } return { results, errors }; } // Usage const prompts = [ 'A sunset over mountains', 'A futuristic city', 'A serene lake', 'A space rocket launch', 'A butterfly on a flower' ]; const { results, errors } = await generateBatch(prompts, { batchSize: 2, guidance_scale: 4.0 }); console.log(`Generated ${results.filter(r => r.success).length} images`); if (errors.length > 0) { console.log(`Failed to generate ${errors.length} images`); } ``` ## Rate Limit Monitoring ```javascript theme={null} class RateLimitTracker { constructor() { this.requests = []; this.warnings = []; } trackRequest() { const now = Date.now(); // Keep only requests from the last minute this.requests = this.requests.filter(time => now - time < 60000); this.requests.push(now); const requestsPerMinute = this.requests.length; if (requestsPerMinute > 45) { // 75% of 60 limit console.warn(`Approaching rate limit: ${requestsPerMinute}/60 requests/minute`); this.warnings.push({ timestamp: now, requestsPerMinute, message: 'Approaching rate limit' }); } } getStats() { const now = Date.now(); const lastMinute = this.requests.filter(time => now - time < 60000); const lastHour = this.requests.filter(time => now - time < 3600000); return { lastMinute: lastMinute.length, lastHour: lastHour.length, warnings: this.warnings.slice(-10) // Last 10 warnings }; } } // Usage const tracker = new RateLimitTracker(); // Wrap your API calls async function trackedRequest(endpoint, params) { tracker.trackRequest(); return requestWithRetry(endpoint, params); } // Check stats periodically setInterval(() => { const stats = tracker.getStats(); if (stats.warnings.length > 0) { console.log('Rate limit warnings:', stats.warnings.length); } }, 10000); ``` ## TypeScript Support ```typescript theme={null} interface GenerationParams { prompt: string; num_images?: number; image_size?: string; guidance_scale?: number; num_inference_steps?: number; seed?: number; } interface VideoParams { prompt: string; duration?: string; aspect_ratio?: string; seed?: number; } interface ImageResult { url: string; width: number; height: number; content_type: string; } interface VideoResult { url: string; duration: number; width: number; height: number; content_type: string; } interface APIResponse { images?: T[]; videos?: T[]; seed: number; has_nsfw_concepts?: boolean[]; timings: { inference: number; }; } class TypedFiremoonClient { constructor(private apiKey: string, private baseUrl = 'https://firemoon.studio/api/v1') {} private async request(endpoint: string, params: any): Promise> { const response = await fetch(`${this.baseUrl}${endpoint}`, { method: 'POST', headers: { 'Authorization': `Bearer ${this.apiKey}`, 'Content-Type': 'application/json' }, body: JSON.stringify(params) }); if (!response.ok) { const error = await response.json(); throw new Error(`API Error: ${error.message}`); } return response.json(); } async generateImage(provider: string, model: string, params: GenerationParams): Promise> { return this.request(`/ ${provider}/${model}`, params); } async generateVideo(provider: string, model: string, params: VideoParams): Promise> { return this.request(`/${provider}/${model}`, params); } } // Usage const client = new TypedFiremoonClient(process.env.FIREMOON_API_KEY!); const imageResult = await client.generateImage('flux', 'dev', { prompt: 'A beautiful sunset', num_images: 2 }); imageResult.images?.forEach(img => { console.log(`Image: ${img.width}x${img.height} - ${img.url}`); }); ``` ## React Hook Example ```javascript theme={null} import { useState, useCallback } from 'react'; function useFiremoonGeneration() { const [loading, setLoading] = useState(false); const [error, setError] = useState(null); const [results, setResults] = useState([]); const generate = useCallback(async (provider, model, params) => { setLoading(true); setError(null); try { const response = await fetch(`/api/v1/${provider}/${model}`, { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.REACT_APP_FIREMOON_API_KEY}`, 'Content-Type': 'application/json' }, body: JSON.stringify(params) }); if (!response.ok) { throw new Error(`HTTP ${response.status}: ${response.statusText}`); } const data = await response.json(); setResults(prev => [...prev, { params, data, timestamp: Date.now() }]); return data; } catch (err) { setError(err.message); throw err; } finally { setLoading(false); } }, []); const clearResults = useCallback(() => { setResults([]); setError(null); }, []); return { generate, loading, error, results, clearResults }; } // Usage in a React component function ImageGenerator() { const { generate, loading, error, results } = useFiremoonGeneration(); const [prompt, setPrompt] = useState(''); const handleGenerate = async () => { try { await generate('flux', 'dev', { prompt, num_images: 1 }); } catch (err) { console.error('Generation failed:', err); } }; return (
setPrompt(e.target.value)} placeholder="Enter a prompt..." /> {error &&
{error}
} {results.map((result, i) => (

Prompt: {result.params.prompt}

{result.data.images?.map((img, j) => ( {`Generated ))}
))}
); } ``` These examples use modern JavaScript features. For older Node.js versions, consider using callbacks or transpiling with Babel. # Python Examples Source: https://docs.firemoon.studio/api-reference/examples/python Complete Python examples for the Firemoon Studio API ## Setup ### Installing Dependencies ```bash theme={null} pip install requests python-dotenv ``` ### Environment Setup ```python theme={null} # .env FIREMOON_API_KEY=your_api_key_here ``` ```python theme={null} # Load environment variables import os from dotenv import load_dotenv load_dotenv() API_KEY = os.getenv('FIREMOON_API_KEY') BASE_URL = 'https://firemoon.studio/api/v1' ``` ## Basic Image Generation ```python theme={null} import requests import os def generate_image(prompt, **kwargs): """Generate an image using FLUX/dev""" response = requests.post( f"{BASE_URL}/flux/dev", headers={ 'Authorization': f'Bearer {API_KEY}', 'Content-Type': 'application/json' }, json={ 'prompt': prompt, 'num_images': kwargs.get('num_images', 1), 'image_size': kwargs.get('image_size', 'landscape_4_3'), 'guidance_scale': kwargs.get('guidance_scale', 3.5), **kwargs } ) response.raise_for_status() return response.json() # Usage try: result = generate_image('A beautiful sunset over mountains') print('Generated image:', result['images'][0]['url']) except requests.exceptions.RequestException as e: print('Error:', str(e)) ``` ## Video Generation ```python theme={null} def generate_video(prompt, **kwargs): """Generate a video using Kling""" response = requests.post( f"{BASE_URL}/kling/kling-2-1-master", headers={ 'Authorization': f'Bearer {API_KEY}', 'Content-Type': 'application/json' }, json={ 'prompt': prompt, 'duration': kwargs.get('duration', '5'), 'aspect_ratio': kwargs.get('aspect_ratio', '16:9'), **kwargs } ) response.raise_for_status() return response.json() # Usage video_result = generate_video( 'A butterfly emerging from its chrysalis', duration='10' ) print('Generated video:', video_result['videos'][0]['url']) ``` ## Character Editing with Ideogram ```python theme={null} def edit_character(prompt, image_url, **kwargs): """Edit a character using Ideogram""" response = requests.post( f"{BASE_URL}/ideogram/v3-character-edit", headers={ 'Authorization': f'Bearer {API_KEY}', 'Content-Type': 'application/json' }, json={ 'prompt': prompt, 'image_url': image_url, 'style': kwargs.get('style', 'realistic'), 'magic_prompt_option': kwargs.get('magic_prompt_option', 'auto'), **kwargs } ) response.raise_for_status() return response.json() # Usage edit_result = edit_character( 'Change the character to wear a red jacket', 'https://example.com/character.jpg' ) print('Edited image:', edit_result['images'][0]['url']) ``` ## Advanced Client Class ```python theme={null} import requests import time from typing import Dict, Any, Optional, Union from dataclasses import dataclass @dataclass class GenerationResult: images: Optional[list] = None videos: Optional[list] = None seed: Optional[int] = None has_nsfw_concepts: Optional[list] = None timings: Optional[Dict[str, float]] = None class FiremoonStudio: def __init__(self, api_key: str, base_url: str = 'https://firemoon.studio/api/v1'): self.api_key = api_key self.base_url = base_url self.session = requests.Session() self.session.headers.update({ 'Authorization': f'Bearer {api_key}', 'Content-Type': 'application/json' }) def _request(self, endpoint: str, params: Dict[str, Any]) -> Dict[str, Any]: response = self.session.post(f"{self.base_url}{endpoint}", json=params) response.raise_for_status() return response.json() def generate_image(self, provider: str, model: str, params: Dict[str, Any]) -> GenerationResult: """Generate images using any provider/model""" result = self._request(f"/{provider}/{model}", params) return GenerationResult(**result) # Convenience methods def flux_dev(self, prompt: str, **kwargs) -> GenerationResult: """Generate images using FLUX/dev""" params = { 'prompt': prompt, 'num_images': 1, 'image_size': 'landscape_4_3', 'guidance_scale': 3.5, **kwargs } return self.generate_image('flux', 'dev', params) def kling_video(self, prompt: str, **kwargs) -> GenerationResult: """Generate videos using Kling""" params = { 'prompt': prompt, 'duration': '5', 'aspect_ratio': '16:9', **kwargs } return self.generate_image('kling', 'kling-2-1-master', params) def ideogram_edit(self, prompt: str, image_url: str, **kwargs) -> GenerationResult: """Edit characters using Ideogram""" params = { 'prompt': prompt, 'image_url': image_url, 'style': 'realistic', **kwargs } return self.generate_image('ideogram', 'v3-character-edit', params) # Usage client = FiremoonStudio(os.getenv('FIREMOON_API_KEY')) # Generate multiple images result = client.flux_dev('A futuristic city', num_images=3) for i, img in enumerate(result.images or []): print(f"Image {i + 1}: {img['url']}") # Generate video video = client.kling_video('A rocket launch') print('Video:', video.videos[0]['url']) ``` ## Error Handling and Retries ```python theme={null} from requests.exceptions import RequestException, Timeout, ConnectionError import logging class FiremoonAPIError(Exception): def __init__(self, message: str, status_code: int = None, details: Dict = None): super().__init__(message) self.status_code = status_code self.details = details or {} def request_with_retry(endpoint: str, params: Dict, max_retries: int = 3): """Make API request with automatic retries""" last_exception = None for attempt in range(max_retries): try: response = requests.post( f"{BASE_URL}{endpoint}", headers={ 'Authorization': f'Bearer {API_KEY}', 'Content-Type': 'application/json' }, json=params, timeout=30 ) if response.status_code == 429: # Rate limited - wait and retry reset_time = response.headers.get('X-RateLimit-Reset') wait_time = min(2 ** attempt, 30) # Exponential backoff, max 30s logging.warning(f"Rate limited. Waiting {wait_time}s before retry {attempt + 1}/{max_retries}") time.sleep(wait_time) continue if not response.ok: error_data = response.json() raise FiremoonAPIError( error_data.get('message', 'Unknown error'), response.status_code, error_data ) return response.json() except (Timeout, ConnectionError) as e: last_exception = e if attempt == max_retries - 1: raise logging.warning(f"Network error (attempt {attempt + 1}/{max_retries}): {e}") time.sleep(2 ** attempt) except RequestException as e: last_exception = e # Don't retry on client errors (4xx except 429) if hasattr(e.response, 'status_code') and 400 <= e.response.status_code < 500 and e.response.status_code != 429: raise FiremoonAPIError(str(e), e.response.status_code) if attempt == max_retries - 1: raise logging.warning(f"Request error (attempt {attempt + 1}/{max_retries}): {e}") raise last_exception # Usage with error handling def safe_generate_image(prompt: str): try: return request_with_retry('/flux/dev', {'prompt': prompt}) except FiremoonAPIError as e: if e.status_code == 400: logging.error(f"Invalid request: {e.details}") elif e.status_code == 401: logging.error("Invalid API key") elif e.status_code == 403: logging.error("Access denied to this provider") else: logging.error(f"API error: {e}") raise except Exception as e: logging.error(f"Unexpected error: {e}") raise ``` ## Batch Processing ```python theme={null} import asyncio import concurrent.futures from typing import List, Tuple, Dict def generate_batch(prompts: List[str], **kwargs) -> Tuple[List[Dict], List[Dict]]: """Generate images for multiple prompts with error handling""" batch_size = kwargs.get('batch_size', 3) results = [] errors = [] def process_prompt(prompt: str, index: int): try: result = request_with_retry('/flux/dev', { 'prompt': prompt, 'num_images': 1, **kwargs }) return {'success': True, 'prompt': prompt, 'result': result, 'index': index} except Exception as e: return {'success': False, 'prompt': prompt, 'error': str(e), 'index': index} # Process in batches to avoid overwhelming the API with concurrent.futures.ThreadPoolExecutor(max_workers=batch_size) as executor: for i in range(0, len(prompts), batch_size): batch = prompts[i:i + batch_size] futures = [ executor.submit(process_prompt, prompt, i + j) for j, prompt in enumerate(batch) ] for future in concurrent.futures.as_completed(futures): result = future.result() if result['success']: results.append(result) else: errors.append(result) # Small delay between batches if i + batch_size < len(prompts): time.sleep(1) return results, errors # Usage prompts = [ 'A sunset over mountains', 'A futuristic city', 'A serene lake', 'A space rocket launch', 'A butterfly on a flower' ] results, errors = generate_batch(prompts, guidance_scale=4.0) print(f"Successfully generated {len(results)} images") if errors: print(f"Failed to generate {len(errors)} images") for error in errors: print(f" - {error['prompt']}: {error['error']}") ``` ## Rate Limit Monitoring ```python theme={null} import time from collections import deque import threading class RateLimitTracker: def __init__(self): self.requests = deque() self.warnings = [] self.lock = threading.Lock() def track_request(self): now = time.time() with self.lock: # Keep only requests from the last minute while self.requests and now - self.requests[0] > 60: self.requests.popleft() self.requests.append(now) requests_per_minute = len(self.requests) if requests_per_minute > 45: # 75% of 60 limit warning = { 'timestamp': now, 'requests_per_minute': requests_per_minute, 'message': 'Approaching rate limit' } self.warnings.append(warning) logging.warning(f"Approaching rate limit: {requests_per_minute}/60 requests/minute") def get_stats(self): now = time.time() with self.lock: last_minute = [t for t in self.requests if now - t < 60] last_hour = [t for t in self.requests if now - t < 3600] return { 'last_minute': len(last_minute), 'last_hour': len(last_hour), 'warnings': self.warnings[-10:] # Last 10 warnings } # Global tracker instance tracker = RateLimitTracker() def tracked_request(endpoint: str, params: Dict): """Make API request with rate limit tracking""" tracker.track_request() return request_with_retry(endpoint, params) # Usage result = tracked_request('/flux/dev', {'prompt': 'A sunset'}) # Check stats stats = tracker.get_stats() print(f"Requests last minute: {stats['last_minute']}") ``` ## Async Support ```python theme={null} import asyncio import aiohttp from typing import List, Dict, Any class AsyncFiremoonStudio: def __init__(self, api_key: str, base_url: str = 'https://firemoon.studio/api/v1'): self.api_key = api_key self.base_url = base_url async def _request(self, endpoint: str, params: Dict[str, Any]) -> Dict[str, Any]: async with aiohttp.ClientSession() as session: async with session.post( f"{self.base_url}{endpoint}", headers={ 'Authorization': f'Bearer {self.api_key}', 'Content-Type': 'application/json' }, json=params ) as response: if not response.ok: error_data = await response.json() raise FiremoonAPIError( error_data.get('message', 'Unknown error'), response.status, error_data ) return await response.json() async def generate_image(self, provider: str, model: str, params: Dict[str, Any]) -> GenerationResult: result = await self._request(f"/{provider}/{model}", params) return GenerationResult(**result) async def generate_batch(self, requests: List[Dict[str, Any]]) -> List[Dict[str, Any]]: """Generate multiple images/videos concurrently""" tasks = [ self.generate_image(req['provider'], req['model'], req['params']) for req in requests ] return await asyncio.gather(*tasks, return_exceptions=True) # Usage async def main(): client = AsyncFiremoonStudio(os.getenv('FIREMOON_API_KEY')) # Generate single image result = await client.generate_image('flux', 'dev', { 'prompt': 'A beautiful sunset', 'num_images': 1 }) print('Image:', result.images[0]['url']) # Generate batch batch_requests = [ { 'provider': 'flux', 'model': 'dev', 'params': {'prompt': 'A mountain landscape', 'num_images': 1} }, { 'provider': 'flux', 'model': 'dev', 'params': {'prompt': 'A city skyline', 'num_images': 1} } ] results = await client.generate_batch(batch_requests) for i, result in enumerate(results): if isinstance(result, Exception): print(f"Request {i + 1} failed: {result}") else: print(f"Request {i + 1} succeeded: {result.images[0]['url']}") asyncio.run(main()) ``` ## Flask Web Application ```python theme={null} from flask import Flask, request, jsonify, render_template import os app = Flask(__name__) client = FiremoonStudio(os.getenv('FIREMOON_API_KEY')) @app.route('/') def index(): return render_template('index.html') @app.route('/generate', methods=['POST']) def generate(): try: data = request.get_json() prompt = data.get('prompt') num_images = data.get('num_images', 1) if not prompt: return jsonify({'error': 'Prompt is required'}), 400 result = client.flux_dev(prompt, num_images=num_images) return jsonify({ 'success': True, 'images': result.images, 'seed': result.seed }) except FiremoonAPIError as e: return jsonify({'error': str(e), 'status_code': e.status_code}), e.status_code except Exception as e: return jsonify({'error': 'Internal server error'}), 500 if __name__ == '__main__': app.run(debug=True) ``` ```html theme={null} Firemoon Studio Image Generator

Generate Images with AI

``` ## Django Integration ```python theme={null} # views.py from django.http import JsonResponse from django.views.decorators.csrf import csrf_exempt from django.views.decorators.http import require_POST import json client = FiremoonStudio(os.getenv('FIREMOON_API_KEY')) @csrf_exempt @require_POST def generate_image_view(request): try: data = json.loads(request.body) prompt = data.get('prompt') num_images = data.get('num_images', 1) if not prompt: return JsonResponse({'error': 'Prompt is required'}, status=400) result = client.flux_dev(prompt, num_images=num_images) return JsonResponse({ 'success': True, 'images': result.images, 'seed': result.seed }) except FiremoonAPIError as e: return JsonResponse( {'error': str(e), 'status_code': e.status_code}, status=e.status_code ) except Exception as e: return JsonResponse({'error': 'Internal server error'}, status=500) # urls.py from django.urls import path from . import views urlpatterns = [ path('generate/', views.generate_image_view, name='generate_image'), ] ``` These examples demonstrate various patterns for integrating with the Firemoon Studio API. Choose the approach that best fits your application's architecture and requirements. # API Overview Source: https://docs.firemoon.studio/api-reference/overview Complete reference for the Firemoon Studio API endpoints ## Base URL ``` https://firemoon.studio/api ``` Most API requests require authentication using an API key in the Authorization header: ``` Authorization: Bearer YOUR_API_KEY ``` Some endpoints like `/api/models` and `/api/models-config/*` are public and don't require authentication. ## Endpoints ### Generation Endpoints | Method | Endpoint | Description | Auth Required | | ------ | ------------------- | --------------------------------------- | ------------- | | `POST` | `/api/v1/{modelid}` | Generate content using a specific model | Yes | ### Account & Usage Endpoints | Method | Endpoint | Description | Auth Required | | ------ | ---------------------- | ---------------------------------- | ------------- | | `GET` | `/api/credits/balance` | Get your current credit balance | Yes | | `GET` | `/api/generations` | Get your generation history | Yes | | `GET` | `/api/usage` | Get usage statistics and analytics | Yes | ## Response Format All generation endpoints return a consistent response structure: ```json theme={null} { "images": [ { "url": "https://blob.vercel-storage.com/...", "width": 1024, "height": 768, "content_type": "image/jpeg" } ], "seed": 123456789, "has_nsfw_concepts": [false], "timings": { "inference": 2.5 } } ``` For video generation, the response includes video URLs instead of images: ```json theme={null} { "videos": [ { "url": "https://blob.vercel-storage.com/...", "duration": 5, "width": 1920, "height": 1088, "content_type": "video/mp4" } ], "seed": 123456789, "timings": { "inference": 15.2 } } ``` ## Error Responses ### 401 Unauthorized ```json theme={null} { "error": "Invalid API key", "message": "Please provide a valid API key in the Authorization header" } ``` ### 403 Forbidden ```json theme={null} { "error": "Access denied", "message": "Your API key does not have access to provider: flux" } ``` ### 404 Not Found ```json theme={null} { "error": "Model not found", "message": "Model configuration not found for flux/invalid-model" } ``` ### 429 Too Many Requests ```json theme={null} { "error": "Rate limit exceeded", "message": "Rate limit exceeded. Try again in 45 seconds.", "resetAt": "2025-10-23T10:30:00.000Z" } ``` ### 400 Bad Request ```json theme={null} { "error": "Invalid input", "message": "Input validation failed", "errors": [ "Missing required field: prompt" ] } ``` ### 402 Payment Required ```json theme={null} { "error": "Insufficient credits", "message": "Insufficient credits to generate content" } ``` **Common causes:** * Credit balance is too low for the requested operation * Cost exceeds available balance ### 500 Internal Server Error ```json theme={null} { "error": "Generation failed", "message": "Failed to generate image: timeout" } ``` # Authentication Source: https://docs.firemoon.studio/essentials/authentication How to authenticate with the Firemoon Studio API ## API Key Authentication All requests to the Firemoon Studio API require authentication using an API key in the `Authorization` header. ## Getting Your API Key Create your API key directly from the Firemoon Studio dashboard: 1. Sign in to [Firemoon Studio](https://firemoon.studio) 2. Navigate to the [API Keys page](https://firemoon.studio/keys) 3. Click "Add key" button 4. Enter a description (e.g., "Production API key" or "Development key") 5. Click "Create key" 6. **Copy your API key immediately** - you won't be able to see it again after closing the dialog Keep your API key secure and never share it publicly. Once created, store it safely as you cannot view it again in the dashboard. ### Managing API Keys You can create multiple API keys for different purposes: * **Development**: For local testing and development * **Staging**: For staging environment testing * **Production**: For live production applications Each key can be deleted individually if compromised or no longer needed. ## Using Your API Key Include the API key in the `Authorization` header with the `Bearer` prefix: ``` Authorization: Bearer your_api_key_here ``` ## Example Requests ```javascript title="JavaScript" theme={null} const response = await fetch('https://firemoon.studio/api/v1/flux/dev', { method: 'POST', headers: { 'Authorization': 'Bearer your_api_key_here', 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt: 'A beautiful sunset' }) }); const result = await response.json(); console.log('Generated image:', result.images[0].url); ``` ```python title="Python" theme={null} import requests response = requests.post( 'https://firemoon.studio/api/v1/flux/dev', headers={ 'Authorization': 'Bearer your_api_key_here', 'Content-Type': 'application/json' }, json={'prompt': 'A beautiful sunset'} ) result = response.json() print('Generated image:', result['images'][0]['url']) ``` ## Security Best Practices ### Environment Variables Store your API key as an environment variable: ```bash theme={null} # .env FIREMOON_API_KEY=your_api_key_here ``` ```javascript title="JavaScript" theme={null} // JavaScript const apiKey = process.env.FIREMOON_API_KEY; ``` ```python title="Python" theme={null} # Python import os api_key = os.getenv('FIREMOON_API_KEY') ``` ### Key Rotation * Rotate API keys regularly (recommended: every 30-90 days) * Use different keys for different environments (dev/staging/prod) * Immediately revoke compromised keys ### Monitoring * Monitor API usage in your dashboard * Set up alerts for unusual activity * Log authentication failures ## API Key Management ### Creating Keys via API You can also create API keys programmatically using the API Keys endpoint: ```bash theme={null} curl -X POST https://firemoon.studio/api/keys \ -H "Authorization: Bearer YOUR_SESSION_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "description": "Production API key", "scope": "full_access" }' ``` API key creation requires authentication via your user session. For automated key management, use the dashboard at [firemoon.studio/keys](https://firemoon.studio/keys). ## Troubleshooting ### 401 Unauthorized * Verify your API key is correct * Check that you're using the `Bearer` prefix * Ensure the key hasn't expired ### 403 Forbidden * Confirm your key has access to the requested provider * Check if you've exceeded rate limits * Verify your account is in good standing ## Support Need help with authentication? * Visit the [API Keys dashboard](https://firemoon.studio/keys) to create and manage your keys * Check our [documentation](/quickstart) for examples * Contact us at [hi@firemoon.studio](mailto:hi@firemoon.studio) for additional support # Error Handling Source: https://docs.firemoon.studio/essentials/error-handling How to handle errors and edge cases in the Firemoon Studio API ## Error Response Format All API errors follow a consistent format: ```json theme={null} { "error": "ErrorType", "message": "Human-readable error message", "details": { /* optional additional information */ } } ``` ## Common Error Codes ### 400 Bad Request Invalid input parameters or malformed requests. ```json theme={null} { "error": "Invalid input", "message": "Input validation failed", "errors": [ "Missing required field: prompt", "Invalid value for image_size: must be one of [square_hd, ...]" ] } ``` **Common causes:** * Missing required fields * Invalid parameter values * Malformed JSON * Unsupported image sizes or formats ### 401 Unauthorized Invalid or missing API key. ```json theme={null} { "error": "Invalid API key", "message": "Please provide a valid API key in the Authorization header" } ``` **Common causes:** * Missing Authorization header * Invalid API key * Expired API key * Wrong header format (missing "Bearer " prefix) ### 403 Forbidden API key doesn't have access to requested resource. ```json theme={null} { "error": "Access denied", "message": "Your API key does not have access to provider: kling" } ``` **Common causes:** * API key tier restrictions * Provider not available in your plan * Account suspended ### 402 Payment Required Insufficient credits to complete the operation. ```json theme={null} { "error": "Insufficient credits", "message": "Insufficient credits to generate content" } ``` **Common causes:** * Credit balance is too low * Cost of generation exceeds available balance * Account needs to add credits **How to handle:** * Check your balance using `/api/credits/balance` * Add credits via the dashboard or payment endpoint * Implement balance checks before expensive operations ### 404 Not Found Requested resource doesn't exist. ```json theme={null} { "error": "Model not found", "message": "Model configuration not found for flux/invalid-model" } ``` **Common causes:** * Invalid provider name * Invalid model name * Typo in endpoint URL ### 429 Too Many Requests Rate limit exceeded. ```json theme={null} { "error": "Rate limit exceeded", "message": "Rate limit exceeded. Try again in 45 seconds.", "resetAt": "2025-10-23T10:30:00.000Z" } ``` **Common causes:** * Too many requests per minute * Daily/monthly quota exceeded ### 500 Internal Server Error Server-side error. ```json theme={null} { "error": "Generation failed", "message": "Failed to generate image: timeout" } ``` **Common causes:** * Model inference timeout * Provider service unavailable * Internal system errors ## Error Handling Patterns ### JavaScript/TypeScript ```javascript theme={null} class FiremoonAPIError extends Error { constructor(response) { super(response.message); this.name = 'FiremoonAPIError'; this.status = response.status; this.error = response.error; this.details = response.details; } } async function generateImage(params) { try { const response = await fetch('https://firemoon.studio/api/v1/flux/dev', { method: 'POST', headers: { 'Authorization': `Bearer ${process.env.FIREMOON_API_KEY}`, 'Content-Type': 'application/json' }, body: JSON.stringify(params) }); if (!response.ok) { const errorData = await response.json(); throw new FiremoonAPIError({ status: response.status, ...errorData }); } return await response.json(); } catch (error) { if (error instanceof FiremoonAPIError) { // Handle API errors switch (error.status) { case 400: console.error('Invalid request:', error.details); // Fix input parameters break; case 401: console.error('Authentication failed'); // Refresh API key or re-authenticate break; case 402: console.error('Insufficient credits'); // Check balance and add credits if needed break; case 429: console.error('Rate limited, retrying...'); // Implement backoff and retry break; case 500: console.error('Server error:', error.message); // Log for debugging, may be transient break; default: console.error('Unexpected error:', error); } } else { // Handle network errors console.error('Network error:', error); } throw error; } } ``` ### Python ```python theme={null} import requests from requests.exceptions import RequestException, Timeout import time class FiremoonAPIError(Exception): def __init__(self, response): self.status_code = response.status_code self.error = response.get('error') self.message = response.get('message') self.details = response.get('details') super().__init__(self.message) def generate_image(params, max_retries=3): url = 'https://firemoon.studio/api/v1/flux/dev' headers = { 'Authorization': f'Bearer {os.getenv("FIREMOON_API_KEY")}', 'Content-Type': 'application/json' } for attempt in range(max_retries): try: response = requests.post( url, json=params, headers=headers, timeout=30 ) if response.status_code == 200: return response.json() # Handle specific error codes if response.status_code == 429: reset_time = response.headers.get('X-RateLimit-Reset') wait_time = min(2 ** attempt, 30) # Exponential backoff, max 30s print(f"Rate limited. Waiting {wait_time}s...") time.sleep(wait_time) continue # Raise custom error for other status codes error_data = response.json() raise FiremoonAPIError(error_data) except Timeout: print(f"Request timeout (attempt {attempt + 1}/{max_retries})") if attempt == max_retries - 1: raise time.sleep(2 ** attempt) except RequestException as e: print(f"Network error (attempt {attempt + 1}/{max_retries}): {e}") if attempt == max_retries - 1: raise time.sleep(2 ** attempt) raise Exception("Max retries exceeded") ``` ## Retry Logic ### Exponential Backoff ```javascript theme={null} async function retryWithBackoff(fn, maxRetries = 3, baseDelay = 1000) { for (let attempt = 0; attempt < maxRetries; attempt++) { try { return await fn(); } catch (error) { if (error.status === 429 || error.status >= 500) { const delay = baseDelay * Math.pow(2, attempt); console.log(`Retrying in ${delay}ms...`); await new Promise(resolve => setTimeout(resolve, delay)); continue; } throw error; } } throw new Error('Max retries exceeded'); } // Usage const result = await retryWithBackoff(() => generateImage({ prompt: 'A sunset' }) ); ``` ### Circuit Breaker Pattern ```javascript theme={null} class CircuitBreaker { constructor(failureThreshold = 5, recoveryTimeout = 60000) { this.failureThreshold = failureThreshold; this.recoveryTimeout = recoveryTimeout; this.failureCount = 0; this.lastFailureTime = null; this.state = 'CLOSED'; // CLOSED, OPEN, HALF_OPEN } async execute(fn) { if (this.state === 'OPEN') { if (Date.now() - this.lastFailureTime > this.recoveryTimeout) { this.state = 'HALF_OPEN'; } else { throw new Error('Circuit breaker is OPEN'); } } try { const result = await fn(); this.onSuccess(); return result; } catch (error) { this.onFailure(); throw error; } } onSuccess() { this.failureCount = 0; this.state = 'CLOSED'; } onFailure() { this.failureCount++; this.lastFailureTime = Date.now(); if (this.failureCount >= this.failureThreshold) { this.state = 'OPEN'; } } } // Usage const breaker = new CircuitBreaker(); const result = await breaker.execute(() => generateImage({ prompt: 'A sunset' }) ); ``` ## Validation ### Input Validation ```javascript theme={null} function validateGenerationParams(params) { const required = ['prompt']; const missing = required.filter(field => !params[field]); if (missing.length > 0) { throw new Error(`Missing required fields: ${missing.join(', ')}`); } if (params.prompt && params.prompt.length > 1000) { throw new Error('Prompt too long (max 1000 characters)'); } if (params.num_images && (params.num_images < 1 || params.num_images > 4)) { throw new Error('num_images must be between 1 and 4'); } // Add more validation as needed } async function safeGenerateImage(params) { validateGenerationParams(params); return await generateImage(params); } ``` ## Monitoring and Logging ### Error Tracking ```javascript theme={null} class ErrorTracker { constructor() { this.errors = []; } track(error) { this.errors.push({ timestamp: new Date(), error: error.message, status: error.status, stack: error.stack }); // Keep only last 100 errors if (this.errors.length > 100) { this.errors.shift(); } } getErrorStats() { const now = Date.now(); const lastHour = this.errors.filter(e => now - e.timestamp < 3600000); return { total: this.errors.length, lastHour: lastHour.length, byStatus: lastHour.reduce((acc, e) => { acc[e.status] = (acc[e.status] || 0) + 1; return acc; }, {}) }; } } // Usage const tracker = new ErrorTracker(); try { await generateImage({ prompt: 'A sunset' }); } catch (error) { tracker.track(error); console.log('Error stats:', tracker.getErrorStats()); } ``` ## Best Practices 1. **Always check response status** before processing 2. **Implement proper retry logic** with exponential backoff 3. **Validate input** before making requests 4. **Log errors** for debugging and monitoring 5. **Handle rate limits** gracefully 6. **Use circuit breakers** for resilient error handling 7. **Provide meaningful error messages** to users 8. **Monitor error rates** and alert on anomalies Most errors are transient and can be resolved with retries. Persistent errors may indicate API key issues or account problems. # Firemoon Studio API Source: https://docs.firemoon.studio/index Lightning fast AI inference at scale. Deploy production-ready AI models in milliseconds with 90% lower costs and sub-second response times. ## Welcome to Firemoon Studio Deploy production-ready AI models in milliseconds. We've generated over 50M+ images with our blazing-fast, cost-optimized inference platform. **Ready to get started?** [Create your API key →](https://firemoon.studio/keys) ## Quick Start Get up and running with the Firemoon Studio API in minutes. Follow our quickstart guide to make your first API call. ## Supported Providers We support the industry's leading AI models across multiple providers. Blazing fast image generation with enhanced creative control. High-quality image generation with character editing capabilities. Professional video generation with cinematic quality. Advanced AI models for creative content generation. Google's latest video generation technology. Specialized models for unique creative applications. ## API Features Sub-second response times for image and video generation. 90% lower costs compared to traditional AI inference platforms. Enterprise-grade reliability with 99.9% uptime. Access models from FLUX, Ideogram, Kling, and more in one API. ## API Reference Everything you need to integrate with the Firemoon Studio API. Complete API documentation with examples in multiple languages. ## Code Examples Node.js and browser examples. Python SDK and requests examples. Command-line examples for testing. # FLUX Provider Source: https://docs.firemoon.studio/providers/flux Fast, high-quality image generation with FLUX models ## Overview FLUX is optimized for speed and creative control. It delivers sub-second inference times while maintaining high image quality. ## Available Models ### FLUX/dev The primary FLUX model optimized for both speed and quality. **Endpoint:** `POST /api/v1/flux/dev` **Best for:** * Rapid prototyping * Content creation workflows * Real-time applications * High-volume generation **Performance:** * **Inference time:** \~0.5-2 seconds * **Quality:** High * **Cost:** Low ## Parameters ### Required Parameters | Parameter | Type | Description | | --------- | ------ | --------------------------------------------------------------- | | `prompt` | string | Text description of the image to generate (max 1000 characters) | ### Optional Parameters | Parameter | Type | Default | Description | | --------------------- | ------ | ----------------- | --------------------------------------- | | `num_images` | number | 1 | Number of images to generate (1-4) | | `image_size` | string | "landscape\_4\_3" | Image dimensions | | `guidance_scale` | number | 3.5 | How closely to follow the prompt (1-20) | | `num_inference_steps` | number | 28 | Number of denoising steps (1-50) | | `seed` | number | random | Random seed for reproducible results | ### Image Sizes | Size | Dimensions | Aspect Ratio | | ---------------- | ---------- | ------------ | | `square_hd` | 1024×1024 | 1:1 | | `square` | 512×512 | 1:1 | | `portrait_4_3` | 768×1024 | 3:4 | | `portrait_16_9` | 576×1024 | 9:16 | | `landscape_4_3` | 1024×768 | 4:3 | | `landscape_16_9` | 1024×576 | 16:9 | ## Examples ### Basic Image Generation ```javascript title="JavaScript" theme={null} const response = await fetch('https://firemoon.studio/api/v1/flux/dev', { method: 'POST', headers: { 'Authorization': 'Bearer your_api_key', 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt: 'A serene mountain landscape at sunset', num_images: 1, image_size: 'landscape_16_9' }) }); const result = await response.json(); console.log('Image URL:', result.images[0].url); ``` ```python title="Python" theme={null} import requests response = requests.post( 'https://firemoon.studio/api/v1/flux/dev', headers={ 'Authorization': 'Bearer your_api_key', 'Content-Type': 'application/json' }, json={ 'prompt': 'A serene mountain landscape at sunset', 'num_images': 1, 'image_size': 'landscape_16_9' } ) result = response.json() print('Image URL:', result['images'][0]['url']) ``` ### Advanced Generation with Control ```javascript title="JavaScript" theme={null} const response = await fetch('https://firemoon.studio/api/v1/flux/dev', { method: 'POST', headers: { 'Authorization': 'Bearer your_api_key', 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt: 'A futuristic city with flying cars, cyberpunk style, highly detailed', num_images: 2, image_size: 'landscape_16_9', guidance_scale: 7.5, // More creative control num_inference_steps: 35, // Higher quality seed: 12345 // Reproducible results }) }); const result = await response.json(); result.images.forEach((image, index) => { console.log(`Image ${index + 1}:`, image.url); }); ``` ```python theme={null} import requests def generate_flux_image(prompt, **kwargs): response = requests.post( 'https://firemoon.studio/api/v1/flux/dev', headers={ 'Authorization': 'Bearer your_api_key', 'Content-Type': 'application/json' }, json={ 'prompt': prompt, 'num_images': kwargs.get('num_images', 1), 'image_size': kwargs.get('image_size', 'landscape_4_3'), 'guidance_scale': kwargs.get('guidance_scale', 3.5), **kwargs } ) response.raise_for_status() return response.json() # Usage result = generate_flux_image( 'A futuristic city with flying cars, cyberpunk style, highly detailed', num_images=2, image_size='landscape_16_9', guidance_scale=7.5, num_inference_steps=35, seed=12345 ) for image in result['images']: print(f"Generated image: {image['url']}") ``` ## Best Practices ### Prompt Engineering **Do:** * Be specific and descriptive * Include style references (e.g., "in the style of impressionist painting") * Mention lighting and mood * Specify composition elements **Don't:** * Use negative prompts (not supported) * Be too vague or abstract * Include copyrighted character names ### Performance Optimization 1. **Use lower guidance\_scale** for faster generation 2. **Reduce num\_inference\_steps** for speed over quality 3. **Generate multiple images** in one request instead of separate calls 4. **Cache successful seeds** for reproducible variations ### Quality vs Speed Trade-offs | Use Case | guidance\_scale | num\_inference\_steps | Expected Time | | --------------- | --------------- | --------------------- | ------------- | | Fast draft | 2.0-3.0 | 20-25 | 0.5-1.0s | | Balanced | 3.5-5.0 | 25-30 | 1.0-1.5s | | High quality | 5.0-7.5 | 30-40 | 1.5-2.5s | | Maximum quality | 7.5+ | 40-50 | 2.5-4.0s | ## Response Format ```json theme={null} { "images": [ { "url": "https://blob.vercel-storage.com/...", "width": 1024, "height": 768, "content_type": "image/jpeg" } ], "seed": 123456789, "has_nsfw_concepts": [false], "timings": { "inference": 1.2 } } ``` ## Error Handling FLUX is generally very reliable, but you may encounter: * **400 Bad Request**: Invalid parameters or prompt too long * **429 Too Many Requests**: Rate limit exceeded * **500 Internal Server Error**: Rare inference failures Implement proper retry logic for 500 errors and backoff for 429 errors. ## Pricing FLUX images are billed at our standard image generation rate. Contact us for volume pricing. FLUX/dev is our recommended model for most use cases due to its excellent balance of speed, quality, and cost. # Kling Provider Source: https://docs.firemoon.studio/providers/kling Professional video generation with Kling AI models ## Overview Kling provides cinematic-quality video generation with smooth motion and professional results. Perfect for marketing videos, social media content, and storytelling. ## Available Models ### kling-2-1-master The latest Kling video generation model with enhanced quality and motion smoothness. **Endpoint:** `POST /api/v1/kling/kling-2-1-master` **Best for:** * Marketing and promotional videos * Social media content * Product demonstrations * Storytelling and narratives **Performance:** * **Inference time:** 10-30 seconds (depending on duration) * **Quality:** Professional cinematic * **Cost:** Medium ## Parameters ### Required Parameters | Parameter | Type | Description | | --------- | ------ | ----------------------------------------- | | `prompt` | string | Description of the video scene and action | ### Optional Parameters | Parameter | Type | Default | Description | | -------------- | ------ | ------- | --------------------------------------- | | `duration` | string | "5" | Video duration in seconds ("5" or "10") | | `aspect_ratio` | string | "16:9" | Video aspect ratio ("16:9" or "9:16") | | `seed` | number | random | Random seed for reproducible results | ## Examples ### Basic Video Generation ```javascript title="JavaScript" theme={null} const response = await fetch('https://firemoon.studio/api/v1/kling/kling-2-1-master', { method: 'POST', headers: { 'Authorization': 'Bearer your_api_key', 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt: 'A butterfly emerging from its chrysalis and flying away', duration: '5', aspect_ratio: '16:9' }) }); const result = await response.json(); console.log('Video URL:', result.videos[0].url); ``` ```python title="Python" theme={null} import requests response = requests.post( 'https://firemoon.studio/api/v1/kling/kling-2-1-master', headers={ 'Authorization': 'Bearer your_api_key', 'Content-Type': 'application/json' }, json={ 'prompt': 'A butterfly emerging from its chrysalis and flying away', 'duration': '5', 'aspect_ratio': '16:9' } ) result = response.json() print('Video URL:', result['videos'][0]['url']) ``` ### Marketing Video ```javascript title="JavaScript" theme={null} const response = await fetch('https://firemoon.studio/api/v1/kling/kling-2-1-master', { method: 'POST', headers: { 'Authorization': 'Bearer your_api_key', 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt: 'A sleek electric car driving through a futuristic city at sunset, smooth camera movement following the vehicle', duration: '10', aspect_ratio: '16:9', seed: 12345 }) }); const result = await response.json(); console.log('Marketing video:', result.videos[0].url); ``` ```python title="Python" theme={null} import requests response = requests.post( 'https://firemoon.studio/api/v1/kling/kling-2-1-master', headers={ 'Authorization': 'Bearer your_api_key', 'Content-Type': 'application/json' }, json={ 'prompt': 'A sleek electric car driving through a futuristic city at sunset, smooth camera movement following the vehicle', 'duration': '10', 'aspect_ratio': '16:9', 'seed': 12345 } ) result = response.json() print('Marketing video:', result['videos'][0]['url']) ``` ## Response Format ```json theme={null} { "videos": [ { "url": "https://blob.vercel-storage.com/...", "duration": 5, "width": 1920, "height": 1088, "content_type": "video/mp4" } ], "seed": 123456789, "timings": { "inference": 15.2 } } ``` ## Best Practices ### Prompt Engineering for Video **Include motion and action:** * "A car driving down a winding road" * "Waves crashing on the shore" * "A bird flying through the sky" **Specify camera movement:** * "Smooth camera pan across the landscape" * "Drone shot flying over the city" * "Tracking shot following the subject" **Describe timing and pacing:** * "Slow motion water droplets falling" * "Fast-paced city traffic" * "Gentle floating motion" ### Video Optimization 1. **Keep prompts concise** but descriptive (under 200 characters recommended) 2. **Specify duration** based on your needs (5s for social media, 10s for detailed scenes) 3. **Choose aspect ratio** to match your platform (16:9 for YouTube, 9:16 for TikTok/Instagram) 4. **Use seeds** for consistent variations ## Pricing Video generation is billed per second of output. Contact us for detailed pricing based on your usage volume. ## Current Limitations * Maximum duration: 10 seconds * Supported aspect ratios: 16:9 and 9:16 * Videos are generated at 1080p resolution Kling videos typically take 10-30 seconds to generate. Consider implementing async processing for better user experience. # MiniMax Provider Source: https://docs.firemoon.studio/providers/minimax Advanced multimodal AI for creative content generation ## Overview MiniMax provides advanced multimodal AI capabilities for complex creative tasks, combining text, image, and other modalities for sophisticated content generation. ## Available Models ### hailuo-02 The latest multimodal model from MiniMax, capable of advanced creative tasks and content generation. **Endpoint:** `POST /api/v1/minimax/hailuo-02` **Best for:** * Complex creative workflows * Multimodal content generation * Advanced AI applications * Research and experimentation **Performance:** * **Inference time:** 10-20 seconds * **Quality:** High versatility * **Cost:** Medium-High ## Parameters ### Required Parameters | Parameter | Type | Description | | --------- | ------ | ------------------------------------------ | | `prompt` | string | Detailed description of the desired output | ### Optional Parameters | Parameter | Type | Default | Description | | -------------- | ------ | ---------- | ------------------------------------ | | `aspect_ratio` | string | "1:1" | Output aspect ratio | | `style` | string | "auto" | Generation style preference | | `quality` | string | "standard" | Quality level: "standard", "high" | | `seed` | number | random | Random seed for reproducible results | ## Examples ### Creative Content Generation ```javascript title="JavaScript" theme={null} const response = await fetch('https://firemoon.studio/api/v1/minimax/hailuo-02', { method: 'POST', headers: { 'Authorization': 'Bearer your_api_key', 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt: 'A surreal landscape where trees grow musical instruments instead of leaves', aspect_ratio: '16:9', style: 'artistic', quality: 'high' }) }); const result = await response.json(); console.log('Generated image:', result.images[0].url); ``` ```python title="Python" theme={null} import requests response = requests.post( 'https://firemoon.studio/api/v1/minimax/hailuo-02', headers={ 'Authorization': 'Bearer your_api_key', 'Content-Type': 'application/json' }, json={ 'prompt': 'A surreal landscape where trees grow musical instruments instead of leaves', 'aspect_ratio': '16:9', 'style': 'artistic', 'quality': 'high' } ) result = response.json() print('Generated image:', result['images'][0]['url']) ``` ## Response Format ```json theme={null} { "images": [ { "url": "https://blob.vercel-storage.com/...", "width": 1024, "height": 1024, "content_type": "image/jpeg" } ], "seed": 123456789, "timings": { "inference": 12.3 } } ``` ## Best Practices ### Advanced Prompt Engineering **Leverage multimodal thinking:** * "Combine elements of steampunk machinery with natural landscapes" * "A portrait that blends human features with architectural elements" **Specify complexity levels:** * "Highly detailed and intricate design" * "Minimalist composition with deep symbolic meaning" ### Use Cases * **Artistic Exploration**: Experimental and avant-garde content * **Brand Innovation**: Unique visual identities * **Research**: Testing novel AI capabilities * **Creative Direction**: Complex visual concepts ## Pricing MiniMax generation is billed at a premium rate due to its advanced capabilities. Contact us for detailed pricing. MiniMax is designed for sophisticated creative workflows and experimental applications. For simpler tasks, consider FLUX or Ideogram first. # Nano Banana Provider Source: https://docs.firemoon.studio/providers/nano-banana Experimental and specialized models for unique creative applications ## Overview Nano Banana offers experimental and specialized AI models for cutting-edge creative applications, research, and unique use cases that require specialized capabilities. ## Available Models ### edit Experimental editing model with unique capabilities for specialized creative tasks. **Endpoint:** `POST /api/v1/nano-banana/edit` **Best for:** * Experimental creative workflows * Research and development * Niche creative applications * Advanced AI experimentation **Performance:** * **Inference time:** Variable (5-20 seconds) * **Quality:** Specialized capabilities * **Cost:** Variable ## Parameters ### Required Parameters | Parameter | Type | Description | | --------- | ------ | ---------------------------------------------- | | `prompt` | string | Specialized prompt for experimental generation | ### Optional Parameters | Parameter | Type | Default | Description | | -------------- | ------ | -------------- | ------------------------------------ | | `mode` | string | "experimental" | Generation mode | | `intensity` | number | 0.5 | Effect intensity (0.0-1.0) | | `aspect_ratio` | string | "1:1" | Output aspect ratio | | `seed` | number | random | Random seed for reproducible results | ## Examples ### Experimental Generation ```javascript title="JavaScript" theme={null} const response = await fetch('https://firemoon.studio/api/v1/nano-banana/edit', { method: 'POST', headers: { 'Authorization': 'Bearer your_api_key', 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt: 'Create an abstract representation using quantum field theory visualization', mode: 'experimental', intensity: 0.8, aspect_ratio: '16:9' }) }); const result = await response.json(); console.log('Experimental result:', result.images[0].url); ``` ```python title="Python" theme={null} import requests response = requests.post( 'https://firemoon.studio/api/v1/nano-banana/edit', headers={ 'Authorization': 'Bearer your_api_key', 'Content-Type': 'application/json' }, json={ 'prompt': 'Create an abstract representation using quantum field theory visualization', 'mode': 'experimental', 'intensity': 0.8, 'aspect_ratio': '16:9' } ) result = response.json() print('Experimental result:', result['images'][0]['url']) ``` ### Research Application ```javascript title="JavaScript" theme={null} const response = await fetch('https://firemoon.studio/api/v1/nano-banana/edit', { method: 'POST', headers: { 'Authorization': 'Bearer your_api_key', 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt: 'Generate a visualization of neural network activation patterns', mode: 'research', intensity: 0.9, seed: 42 }) }); const result = await response.json(); console.log('Research visualization:', result.images[0].url); ``` ```python title="Python" theme={null} import requests response = requests.post( 'https://firemoon.studio/api/v1/nano-banana/edit', headers={ 'Authorization': 'Bearer your_api_key', 'Content-Type': 'application/json' }, json={ 'prompt': 'Generate a visualization of neural network activation patterns', 'mode': 'research', 'intensity': 0.9, 'seed': 42 } ) result = response.json() print('Research visualization:', result['images'][0]['url']) ``` ## Response Format ```json theme={null} { "images": [ { "url": "https://blob.vercel-storage.com/...", "width": 1024, "height": 1024, "content_type": "image/jpeg" } ], "seed": 123456789, "experimental_metadata": { "mode_used": "experimental", "intensity_applied": 0.8, "processing_notes": "Advanced experimental processing applied" }, "timings": { "inference": 14.2 } } ``` ## Best Practices ### Experimental Prompts **Leverage unique capabilities:** * "Generate using quantum-inspired algorithms" * "Apply fractal mathematics to create patterns" * "Use chaos theory principles in composition" **Specify research contexts:** * "Create a visualization for machine learning research" * "Generate abstract representations of complex systems" * "Produce experimental artistic interpretations" ### Use Cases * **Research**: Academic and scientific visualization * **Art**: Experimental and avant-garde creation * **Development**: Testing novel AI capabilities * **Innovation**: Pushing creative boundaries ## Important Notes ### Experimental Nature * Results may vary significantly between requests * Some features are in beta testing * Performance characteristics may change * Not recommended for production applications requiring consistency ### Availability * Features may be limited during testing phases * Contact us for access to specific experimental capabilities * Some modes may require special approval ## Pricing Nano Banana features are priced variably based on the experimental nature and resource requirements. Contact us for detailed pricing information. Nano Banana models are experimental and best suited for research, experimentation, and creative exploration rather than production use cases. # Providers Overview Source: https://docs.firemoon.studio/providers/overview Learn about the AI providers supported by Firemoon Studio ## Supported Providers Firemoon Studio integrates with leading AI model providers to give you access to the best image and video generation models in one unified API. ## Provider Comparison | Provider | Type | Best For | Key Features | | ------------------- | ----------- | ----------------------------------- | --------------------------------------- | | **FLUX** | Image | Fast, high-quality image generation | Sub-second inference, creative control | | **Firemoon Studio** | Image | Specialized artistic styles | Finetuned FLUX models, LoRA integration | | **Ideogram** | Image | Character editing and styling | Precise edits, style consistency | | **Kling** | Video | Cinematic video generation | Professional quality, smooth motion | | **Minimax** | Multi-modal | Creative content | Advanced AI capabilities | | **Google Veo** | Video | High-quality video | Google's latest technology | | **Nano Banana** | Specialized | Unique applications | Experimental models | ## FLUX The fastest image generation available with enhanced creative control. **Models:** * `dev` - Optimized for speed and quality **Use Cases:** * Rapid prototyping * Content creation workflows * Real-time applications **Example:** ```javascript theme={null} const result = await client.generate.image({ provider: 'flux', model: 'dev', prompt: 'A futuristic city skyline', guidance_scale: 3.5 }); ``` ## Ideogram Specialized in character consistency and precise editing capabilities. **Models:** * `v3-character-edit` - Advanced character editing **Use Cases:** * Character design * Product visualization * Brand consistency **Example:** ```javascript theme={null} const result = await client.generate.image({ provider: 'ideogram', model: 'v3-character-edit', prompt: 'Change the character's outfit to blue', image_url: 'https://example.com/character.jpg' }); ``` ## Kling Professional video generation with cinematic quality. **Models:** * `kling-2-1-master` - Latest video generation **Use Cases:** * Marketing videos * Social media content * Storytelling **Example:** ```javascript theme={null} const result = await client.generate.video({ provider: 'kling', model: 'kling-2-1-master', prompt: 'A rocket launching into space', duration: '5', aspect_ratio: '16:9' }); ``` ## Minimax Advanced multimodal AI for creative applications. **Models:** * `hailuo-02` - General purpose creative AI **Use Cases:** * Complex creative tasks * Multimodal content * Advanced AI applications ## Google Veo Google's cutting-edge video generation technology. **Models:** * `google-veo-3-fast` - Fast video generation **Use Cases:** * High-quality video production * Professional content * Research applications ## Nano Banana Experimental and specialized models for unique applications. **Models:** * `nano-banan-edit` - Specialized editing **Use Cases:** * Experimental features * Niche applications * Advanced research ## Firemoon Studio A collection of 40+ finetuned FLUX models specialized for different artistic styles and visual enhancements. **Models:** * `better-faces` - Enhanced facial details and cultural representation * `neon-cyberpunk` - Cyberpunk environments and techno aesthetics * `dnd-darkest-fantasy` - Dark fantasy with Midjourney V6.1 influence * `detail-maximizer` - Maximum image sharpness and quality * And 35+ more specialized styles **Use Cases:** * Artistic style exploration * Character and portrait enhancement * Genre-specific content creation * Creative experimentation **Example:** ```javascript theme={null} const result = await client.generate.image({ provider: 'firemoon-studio', model: 'better-faces', prompt: 'A beautiful portrait with enhanced facial details', lora_scale: 0.6 }); ``` ## Choosing a Provider **For Speed:** Use FLUX for sub-second image generation. **For Quality:** Choose Ideogram for consistent character work or Kling for video. **For Scale:** All providers are optimized for production workloads. **For Experimentation:** Try Nano Banana for cutting-edge features. ## Provider Availability All providers are available in our production API. Some experimental models may have limited availability during beta testing. Provider availability and models may change. Check the [API status page](https://status.firemoon.studio) for current information. # Quickstart Source: https://docs.firemoon.studio/quickstart Get started with the Firemoon Studio API in minutes ## Get started in three steps Generate your first AI image with the Firemoon Studio API. ### Step 1: Create your API key Create your API key directly from the Firemoon Studio dashboard: 1. Sign in to [Firemoon Studio](https://firemoon.studio) 2. Navigate to the [API Keys page](https://firemoon.studio/keys) 3. Click "Add key" and provide a description 4. Copy your API key immediately - you won't be able to see it again! You can create multiple API keys for different environments (development, staging, production). ### Step 2: Make your first API call Generate your first image: ```javascript title="JavaScript" theme={null} const response = await fetch('https://firemoon.studio/api/v1/flux/dev', { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt: 'A beautiful sunset over mountains', num_images: 1, image_size: 'landscape_4_3', guidance_scale: 3.5 }) }); const result = await response.json(); console.log('Generated image:', result.images[0].url); ``` ```python title="Python" theme={null} import requests response = requests.post( 'https://firemoon.studio/api/v1/flux/dev', headers={ 'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' }, json={ 'prompt': 'A beautiful sunset over mountains', 'num_images': 1, 'image_size': 'landscape_4_3', 'guidance_scale': 3.5 } ) result = response.json() print('Generated image:', result['images'][0]['url']) ``` Replace `YOUR_API_KEY` with the API key you created in your dashboard. Create a short video with our Kling integration: ```javascript title="JavaScript" theme={null} const response = await fetch('https://firemoon.studio/api/v1/kling/kling-2-1-master', { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt: 'A butterfly emerging from its chrysalis', duration: '5', aspect_ratio: '16:9' }) }); const result = await response.json(); console.log('Generated video:', result.videos[0].url); ``` ```python title="Python" theme={null} import requests response = requests.post( 'https://firemoon.studio/api/v1/kling/kling-2-1-master', headers={ 'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' }, json={ 'prompt': 'A butterfly emerging from its chrysalis', 'duration': '5', 'aspect_ratio': '16:9' } ) result = response.json() print('Generated video:', result['videos'][0]['url']) ``` ## Next steps Now that you've made your first API call, explore: Complete API documentation with all endpoints. Learn about FLUX, Ideogram, Kling, and other providers. Best practices for API key management. Handle errors and edge cases gracefully. **Need help?** Contact us at [hi@firemoon.studio](mailto:hi@firemoon.studio).