API Documentation
Integrate bitStudio's powerful AI capabilities directly into your applications with our comprehensive API.
Authentication
All API requests require authentication using an API key
Base URL for all API requests:
https://api.bitstudio.ai
Include your API key in the Authorization header:
Authorization: Bearer YOUR_API_KEY
Keep your API keys secure and never share them in public repositories or client-side code.
You can manage your API keys in the API Keys section of your account.
Virtual Try-On API
Combine person and outfit images using AI
POST /images/virtual-try-on
Request Parameters
Parameter | Type | Description | Required |
---|---|---|---|
person_image_id | string | ID of image with type "virtual-try-on-person" | No |
person_image_url | string | URL of a person image to use | No |
outfit_image_id | string | ID of image with type "virtual-try-on-outfit" | No |
outfit_image_url | string | URL of an outfit image to use | No |
outfit_asset_id | string | ID of an outfit asset to use | No |
prompt | string | Optional text description to guide generation | No |
resolution | string | standard or high | No |
num_images | number | Number of output images (1-4) | No |
seed | int | Seed for reproducible generations | No |
To obtain image IDs, you must first upload images using the with the appropriate type. See the Image Upload tab.
Example Request
{ "person_image_id": "VT_PERSON_123", "outfit_image_id": "VT_OUTFIT_456", "prompt": "professional portrait, high quality", "resolution": "high", "num_images": 2, "style": "studio" }
JavaScript Example
const virtualTryOn = async (personImageId, outfitImageId) => { const response = await fetch('https://api.bitstudio.ai/images/virtual-try-on', { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ person_image_id: personImageId, outfit_image_id: outfitImageId, resolution: "standard", num_images: 1 }) }); const results = await response.json(); return results[0]; // Returns the first generated image info }; // After uploading person and outfit images and getting their IDs const tryOnResult = await virtualTryOn('IMG_123', 'IMG_456'); console.log('Generation started:', tryOnResult.id); // Poll for completion const pollForCompletion = async (imageId) => { let complete = false; while (!complete) { const response = await fetch(`https://api.bitstudio.ai/images/${imageId}`, { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }); const imageData = await response.json(); if (imageData.status === 'completed') { complete = true; return imageData; } else if (imageData.status === 'failed') { throw new Error('Image generation failed'); } // Wait 2 seconds before polling again await new Promise(resolve => setTimeout(resolve, 2000)); } }; // Get the completed image const finalImage = await pollForCompletion(tryOnResult.id); console.log('Image is ready:', finalImage.path);
Response Format
[ { "id": "GEN_789", "status": "pending", "task": "virtual-try-on", "estimated_completion": "2024-02-20T15:00:00Z", "credits_used": 2, "source_image_ids": [ "VT_PERSON_123", "VT_OUTFIT_456" ] } ]
Check image status by polling GET /images/{id}. Status will transition from "pending" → "generating" → "completed".
Once completed, the path field will contain the URL to the generated image.
Tips for Best Results
- Person images: Full body, front-facing photos with neutral pose work best
- Outfit images: Clear, isolated garments on white/transparent background
- Resolution: High-quality input images improve output quality
- Timing: Processing typically takes 15-30 seconds per image
Image Upload API
Upload images for processing with specific types
POST /images
Request Format
Images must be uploaded as multipart/form-data with the following fields:
Parameter | Type | Description | Required |
---|---|---|---|
file | file | Image file to upload (JPEG, PNG, WebP) | Yes |
type | string | Type of image (see supported types below) | No |
The API accepts image files up to 10MB. For optimal results, use high-quality images with clear subjects.
Supported Image Types
virtual-try-on-personPerson Image
virtual-try-on-outfitOutfit Image
inpaint-baseBase Image
inpaint-maskMask Image
editEdit Image
inpaint-referenceReference Image
image-to-videoImage to Video Base
Example: Upload Person Image for Virtual Try-On
curl -X POST https://api.bitstudio.ai/images \ -H "Authorization: Bearer YOUR_API_KEY" \ -F "[email protected]" \ -F "type=virtual-try-on-person"
JavaScript Example (Browser)
const uploadImage = async (file, type) => { const formData = new FormData(); formData.append('file', file); formData.append('type', type); const response = await fetch('https://api.bitstudio.ai/images', { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_API_KEY' }, body: formData }); const result = await response.json(); return result; }; // Upload person image const personImg = document.querySelector('#personImageInput').files[0]; const personImageData = await uploadImage(personImg, 'virtual-try-on-person'); // Upload outfit image const outfitImg = document.querySelector('#outfitImageInput').files[0]; const outfitImageData = await uploadImage(outfitImg, 'virtual-try-on-outfit'); // Now use the returned image IDs for virtual try-on console.log('Person Image ID:', personImageData.id); console.log('Outfit Image ID:', outfitImageData.id);
Response Format
{ "id": "IMG_123", "type": "virtual-try-on-person", "path": "https://media.bitstudio.ai/user-content/u123/image.jpg", "status": "completed", "width_px": 1024, "height_px": 1024, "is_generated": false, "for_training": false, "created_timestamp": "2024-02-20T14:30:00Z", "versions": [] }
Use the returned id value in subsequent API calls, such as virtual try-on.
Generate Images
Create images from text prompts
POST /images/generate
Request Parameters
Parameter | Type | Description | Required |
---|---|---|---|
prompt | string | Text description of the image | Yes |
asset_ids | array | Array of trained model IDs to use for generation | No |
num_images | number | Number of images (1-4) | No |
aspect_ratio | string | portrait, landscape, or square | No |
style | string | Visual style to apply (studio or smartphone) | No |
resolution | string | standard or high | No |
model_text | string | Text description of the person/model to generate | No |
outfit_text | string | Text description of the outfit for the model | No |
outfit_image_id | string | ID of an outfit image to apply | No |
outfit_asset_id | string | ID of an outfit asset to apply | No |
set_id | string | ID of a set to use for generation | No |
set_text | string | Text description to modify the set | No |
seed | int | Seed for reproducible generations | No |
Example Request
{ "prompt": "a beautiful sunset over mountains", "num_images": 1, "resolution": "standard", "aspect_ratio": "landscape" }
JavaScript Example
const generateImages = async (prompt) => { const response = await fetch('https://api.bitstudio.ai/images/generate', { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt: prompt, num_images: 1, resolution: "standard", aspect_ratio: "square" }) }); const results = await response.json(); return results[0]; // Returns the first generated image info }; // Call the function to generate an image const generationResult = await generateImages('a beautiful portrait of a woman with blonde hair'); console.log('Generation started:', generationResult.id); // Poll for completion const pollForCompletion = async (imageId) => { let complete = false; while (!complete) { const response = await fetch(`https://api.bitstudio.ai/images/${imageId}`, { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }); const imageData = await response.json(); if (imageData.status === 'completed') { complete = true; return imageData; } else if (imageData.status === 'failed') { throw new Error('Image generation failed'); } // Wait 2 seconds before polling again await new Promise(resolve => setTimeout(resolve, 2000)); } }; // Get the completed image const finalImage = await pollForCompletion(generationResult.id); console.log('Image is ready:', finalImage.path);
Response Format
[ { "id": "GEN_456", "status": "pending", "task": "generate", "estimated_completion": "2024-02-20T15:30:00Z", "credits_used": 1 } ]
Check image status by polling GET /images/{id} until the status is "completed".
Tips for Effective Prompts
- Be specific: Include details about style, lighting, composition, and subject
- Use qualifiers: Words like "beautiful", "detailed", "professional" can improve quality
- Aspect ratio: Choose the right aspect ratio for your intended use case
- Style: The "studio" style tends to produce more polished, professional results
Upscaling
Increase image resolution and create new versions
POST /images/{id}/upscale
Request Parameters
Parameter | Type | Description | Required |
---|---|---|---|
upscale_factor | number | 1, 2 (2x resolution) or 4 (4k) | Yes |
denoise | number | Noise reduction strength (0.05-0.5) - not used for 4k | No |
version_id | string | Specific version to upscale | No |
Example Request
{ "upscale_factor": 2, "denoise": 0.3 }
JavaScript Example
const upscaleImage = async (imageId) => { const response = await fetch(`https://api.bitstudio.ai/images/${imageId}/upscale`, { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ upscale_factor: 2, denoise: 0.3 }) }); const result = await response.json(); return result; }; // Call the function to upscale an image const upscaleResult = await upscaleImage('IMG_123'); console.log('Upscaling started:', upscaleResult.id); // Poll for completion const pollForCompletion = async (imageId) => { let complete = false; while (!complete) { const response = await fetch(`https://api.bitstudio.ai/images/${imageId}`, { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }); const imageData = await response.json(); if (imageData.status === 'completed') { complete = true; return imageData; } else if (imageData.status === 'failed') { throw new Error('Image upscaling failed'); } // Wait 2 seconds before polling again await new Promise(resolve => setTimeout(resolve, 2000)); } }; // Get the upscaled image details const finalImage = await pollForCompletion(upscaleResult[0].id); console.log('Upscaled image is ready:', finalImage);
Response Format
[ { "id": "UPSCALE_123", "status": "pending", "task": "upscale", "source_image_ids": [ "ORIGINAL_123" ], "base_image_version_id": "VERSION_456" } ]
Successful upscaling adds a new version to the original image's versions array with version_type: "upscaled"
Tips for Best Results
- Input quality: Better results with higher quality source images
- Denoise: Higher values (0.3-0.5) for noisy images, lower (0.05-0.2) for clean images
- Processing time: Can take 30-60 seconds depending on image size
Inpainting
Modify specific parts of an image
POST /images/{id}/inpaint
Request Parameters
Parameter | Type | Description | Required |
---|---|---|---|
mask_image_id | string | ID of image with type "inpaint-mask" | Yes |
reference_image_id | string | ID of image with type "inpaint-reference" | No |
prompt | string | Description of desired changes | Yes |
denoise | number | Strength of effect (0.05-1.0) | No |
num_images | number | Number of results to generate (1-4) | No |
Example Request
{ "mask_image_id": "MASK_123", "reference_image_id": "REF_456", "prompt": "Sunny beach with palm trees", "denoise": 1, "num_images": 1 }
JavaScript Example
const inpaintImage = async (imageId, maskImageId, prompt) => { const response = await fetch(`https://api.bitstudio.ai/images/${imageId}/inpaint`, { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ mask_image_id: maskImageId, prompt: prompt, denoise: 1.0, num_images: 1 }) }); const result = await response.json(); return result; }; // Call the function to inpaint an image const inpaintResult = await inpaintImage('BASE_123', 'MASK_456', 'Replace with a beautiful beach'); console.log('Inpainting started:', inpaintResult[0].id); // Poll for completion as in previous examples const finalImage = await pollForCompletion(inpaintResult[0].id); console.log('Inpainted image is ready:', finalImage.path);
Response Format
[ { "id": "INPAINT_123", "status": "pending", "task": "inpaint", "source_image_ids": [ "BASE_123", "MASK_456" ], "estimated_completion": "2024-02-20T15:30:00Z", "credits_used": 1 } ]
Creating a Mask Image
To create a mask image:
- Start with your base image
- Create a black and white mask where:
- White areas: Parts to be replaced/modified
- Black areas: Parts to keep unchanged
- Upload the mask with type=inpaint-mask
- Use the returned mask ID in your inpainting request
Tips for Best Results
- Clear masks: Use solid white for areas to change, black for areas to preserve
- Descriptive prompts: Be specific about what to add in the masked area
- Denoise values: Higher values (0.8-1.0) for more dramatic changes, lower for subtle edits
- Reference images: Use reference images to guide style and content
Image to Video
Transform still images into short video animations
POST /images/{id}/video
Request Parameters
Parameter | Type | Description | Required |
---|---|---|---|
prompt | string | Description of the desired motion | Yes |
Example Request
{ "prompt": "gentle camera zoom, cinematic lighting" }
JavaScript Example
const imageToVideo = async (imageId, prompt) => { const response = await fetch(`https://api.bitstudio.ai/images/${imageId}/video`, { method: 'POST', headers: { 'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' }, body: JSON.stringify({ prompt: prompt, }) }); const result = await response.json(); return result; }; // Call the function to create video from an image const videoResult = await imageToVideo('IMG_123', 'gentle camera zoom in, soft wind in hair'); console.log('Video generation started:', videoResult.id); // Poll for completion as in previous examples const finalVideo = await pollForCompletion(videoResult.id); console.log('Video is ready:', finalVideo.path);
Response Format
{ "id": "VIDEO_123", "status": "pending", "task": "image-to-video", "source_image_id": "IMG_123", "estimated_completion": "2024-02-20T15:45:00Z", "credits_used": 15 }
Once completed, the response will include a video_path field with the URL to the generated video.
Tips for Best Results
- Image composition: Well-framed, clear subjects work best
- Processing time: Typically takes 10 minutes per video
Error Handling
Understanding API errors and how to handle them
Error Response Format
{ "error": "Error message", "code": "ERROR_CODE", "details": {} }
Common Error Codes
Error Code | Description | HTTP Status |
---|---|---|
insufficient_credits | Not enough credits to perform the operation | 402 |
no_active_subscription | No active subscription found | 402 |
upgrade_required | Feature requires a higher tier plan | 402 |
no_training_found | No training found for the specified asset | 404 |
unauthorized | Invalid API key or missing authentication | 401 |
model_not_found | Requested model not found | 404 |
invalid_aspect_ratio | Invalid aspect ratio specified | 400 |
invalid_resolution | Invalid resolution specified | 400 |
internal_server_error | Server error occurred | 500 |
bad_request | Invalid request parameters | 400 |
forbidden | Access to the resource is forbidden | 403 |
RATE_LIMITED | Too many requests (max 10 per second) | 429 |
Feature Restriction Errors
When attempting to use a feature that requires a higher plan tier, you'll receive an upgrade_required
error with additional context:
{ "error": "upgrade_required", "feature": "image_to_video", "current_plan": "Pro", "required_plan": "Ultra" }
Best Practices for Error Handling
- Always check for error responses and handle them gracefully
- Implement exponential backoff for rate limiting errors
- Validate inputs client-side before sending requests
- Check credit balance before making credit-consuming operations
JavaScript Error Handling Example
const callApi = async (endpoint, method, data) => { try { const response = await fetch(`https://api.bitstudio.ai${endpoint}`, { method: method, headers: { 'Authorization': 'Bearer YOUR_API_KEY', 'Content-Type': 'application/json' }, body: data ? JSON.stringify(data) : undefined }); const result = await response.json(); // Check if the response contains an error if (response.status >= 400 || result.error) { throw { status: response.status, code: result.code || 'UNKNOWN_ERROR', message: result.error || 'Unknown error occurred', details: result.details || {} }; } return result; } catch (error) { // Handle specific error codes if (error.code === 'RATE_LIMITED') { console.log('Rate limited. Retrying after a delay...'); // Implement exponential backoff here await new Promise(resolve => setTimeout(resolve, 5000)); return callApi(endpoint, method, data); } if (error.code === 'INSUFFICIENT_CREDITS') { console.error('Not enough credits to perform this operation'); // Redirect user to purchase more credits } // Log and rethrow the error console.error('API Error:', error); throw error; } };
Get Image Status
Retrieve image details and check generation status
GET /images/{id}
Response Format
{ "id": "IMG_123", "status": "completed", "task": "virtual-try-on", "path": "https://media.bitstudio.ai/gen/image.jpg", "versions": [ { "id": "VERSION_123", "version_type": "upscaled", "path": "https://media.bitstudio.ai/gen/upscaled.jpg" } ], "credits_used": 2, "created_timestamp": "2024-02-20T14:30:00Z", "finish_timestamp": "2024-02-20T15:00:00Z" }
Polling for Completion
Most API operations that generate images are asynchronous. Use this endpoint to check the status of operations:
const pollForCompletion = async (imageId) => { let complete = false; while (!complete) { const response = await fetch(`https://api.bitstudio.ai/images/${imageId}`, { headers: { 'Authorization': 'Bearer YOUR_API_KEY' } }); const imageData = await response.json(); if (imageData.status === 'completed') { complete = true; return imageData; } else if (imageData.status === 'failed') { throw new Error('Image processing failed'); } console.log('Current status:', imageData.status); // Wait 2 seconds before polling again await new Promise(resolve => setTimeout(resolve, 2000)); } };
Status Values
Status | Description |
---|---|
pending | Request received, waiting to be processed |
generating | Processing has begun |
completed | Processing is complete, result is ready |
failed | Processing failed, check error details |
Best Practices
- Use exponential backoff: Increase the wait time between polls if processing takes longer
- Check for errors: Always handle the "failed" status explicitly
- Timeout: Implement a reasonable timeout for your polling loop (e.g., 2-3 minutes)
Credit Usage
Understanding credit costs for different operations
Operation | Credit Cost |
---|---|
Standard Resolution Generation | 1 credit per image |
High Resolution Generation | 2 credits per image |
Virtual Try-On (Standard) | 1 credit per image |
Virtual Try-On (High) | 2 credits per image |
Upscaling (1x) | 1 credit per image |
Upscaling (2x) | 2 credits per image |
Upscaling (4k) | 5 credits per image |
Inpainting (standard) | 1 credit per image |
Inpainting (high) | 2 credits per image |
Image to Video | 15 credits per video |
Credits are deducted when the request is made. If the operation fails, credits are automatically refunded.
Frequently Asked Questions
How do I authenticate my API requests?
Include your API key in the Authorization header: 'Authorization: Bearer YOUR_API_KEY'.
Are there rate limits for the API?
Yes, the API is limited to 10 requests per second. If you exceed this limit, you'll receive a RATE_LIMITED error code.
How are credits deducted when using the API?
Credits are deducted when the request is made. If the operation fails, credits are automatically refunded.
What image formats are supported for upload?
The API accepts JPEG, PNG, and WebP formats with a maximum file size of 10MB.
How do I check the status of a generated image?
Poll the GET /images/{id} endpoint until the status changes from 'pending' to 'completed'.
Ready to integrate our API?
Get started with our API to add powerful AI imaging capabilities to your application.