变更: - 创建 docs/ 目录统一管理所有文档 - 移动所有 API 文档到 docs/ 目录 - API_DOCS_INDEX.md - RESTFUL_API_DOCUMENTATION.md - API_SERVICE_README.md - API_CLIENT_EXAMPLES.md - API_SERVICE_GUIDE.md - BRANCH_README.md - openapi.yaml - IOPaint_API.postman_collection.json - UPGRADE_NOTES.md - 更新所有文档间的引用路径 - 更新 README.md 中的文档链接 - 创建 docs/README.md 作为文档入口 优势: ✅ 清晰的目录结构 ✅ 文档集中管理 ✅ 易于查找和维护 ✅ 符合项目规范 🔧 Generated with Claude Code
22 KiB
IOPaint REST API Documentation
Official REST API documentation for IOPaint Watermark Removal Service.
Version: v1
Base URL: https://api.iopaint.com (production) or http://localhost:8080 (development)
Protocol: HTTPS (production), HTTP (development)
Table of Contents
- Introduction
- Authentication
- API Endpoints
- Models
- Error Handling
- Rate Limiting
- Best Practices
- SDKs & Libraries
- Changelog
Introduction
The IOPaint API provides AI-powered watermark removal capabilities through a simple REST API. Built on the LaMa (Large Mask Inpainting) model, it offers fast and high-quality image restoration.
Key Features
- Fast Processing: 1-2 seconds for 1024x1024 images
- High Quality: State-of-the-art AI model
- Simple Integration: Standard REST API with multipart/form-data
- Flexible: Optional mask support for precise control
- Scalable: From hobby projects to enterprise deployments
API Capabilities
| Feature | Status | Description |
|---|---|---|
| Watermark Removal | ✅ Available | Remove watermarks from images |
| Auto Detection | ⏳ Coming Soon | Automatic watermark detection |
| Batch Processing | ⏳ Coming Soon | Process multiple images at once |
| Webhook Callbacks | ⏳ Coming Soon | Async processing with callbacks |
Authentication
The IOPaint API uses API keys for authentication. All requests must include your API key in the request header.
Obtaining an API Key
- Sign up at https://iopaint.com/signup
- Navigate to your Dashboard
- Generate a new API key
- Store it securely (keys cannot be recovered)
Using Your API Key
Include your API key in the X-API-Key header with every request:
X-API-Key: your_api_key_here
Security Best Practices
- ⚠️ Never expose your API key in client-side code
- ✅ Store keys in environment variables
- ✅ Rotate keys periodically
- ✅ Use different keys for development and production
- ✅ Revoke compromised keys immediately
Example
# ✅ Correct
curl https://api.iopaint.com/api/v1/health \
-H "X-API-Key: $IOPAINT_API_KEY"
# ❌ Incorrect (hardcoded key)
curl https://api.iopaint.com/api/v1/health \
-H "X-API-Key: sk_live_1234567890abcdef"
API Endpoints
Base URL
Production: https://api.iopaint.com
Development: http://localhost:8080
Endpoint Overview
| Endpoint | Method | Description |
|---|---|---|
/api/v1/remove-watermark |
POST | Remove watermark from image |
/api/v1/health |
GET | Service health check |
/api/v1/stats |
GET | Account usage statistics |
1. Remove Watermark
Remove watermarks or unwanted objects from images using AI.
Endpoint
POST /api/v1/remove-watermark
Authentication
Required. Include X-API-Key header.
Request Headers
| Header | Type | Required | Description |
|---|---|---|---|
X-API-Key |
string | Yes | Your API key |
Content-Type |
string | Yes | Must be multipart/form-data |
Request Body
Submit as multipart/form-data:
| Field | Type | Required | Max Size | Description |
|---|---|---|---|---|
image |
file | Yes | 10 MB | Image to process (JPEG, PNG, WebP) |
mask |
file | No | 10 MB | Optional mask (white = remove, black = keep) |
Image Requirements
- Formats: JPEG, PNG, WebP
- Max Dimension: 4096px (width or height)
- Max File Size: 10 MB
- Color Mode: RGB (grayscale will be converted)
Mask Requirements
- Format: PNG (8-bit grayscale or RGB)
- Dimension: Must match image size (auto-resized if different)
- White (255): Areas to remove/inpaint
- Black (0): Areas to preserve
- Gray: Partial inpainting (blend)
Response
Success (200 OK)
Returns the processed image as image/png.
Response Headers:
| Header | Type | Description |
|---|---|---|
Content-Type |
string | image/png |
X-Processing-Time |
float | Processing time in seconds |
X-Image-Size |
string | Original image dimensions (e.g., "1024x768") |
Examples
cURL
# Basic usage (no mask)
curl -X POST https://api.iopaint.com/api/v1/remove-watermark \
-H "X-API-Key: $IOPAINT_API_KEY" \
-F "image=@/path/to/image.jpg" \
-o result.png
# With mask
curl -X POST https://api.iopaint.com/api/v1/remove-watermark \
-H "X-API-Key: $IOPAINT_API_KEY" \
-F "image=@/path/to/image.jpg" \
-F "mask=@/path/to/mask.png" \
-o result.png
# Verbose output
curl -X POST https://api.iopaint.com/api/v1/remove-watermark \
-H "X-API-Key: $IOPAINT_API_KEY" \
-F "image=@image.jpg" \
-v \
-o result.png
Python
import requests
url = "https://api.iopaint.com/api/v1/remove-watermark"
headers = {"X-API-Key": "your_api_key_here"}
# Basic usage
with open("image.jpg", "rb") as f:
files = {"image": f}
response = requests.post(url, headers=headers, files=files)
if response.status_code == 200:
with open("result.png", "wb") as f:
f.write(response.content)
print(f"✓ Success! Processing time: {response.headers['X-Processing-Time']}s")
else:
print(f"✗ Error {response.status_code}: {response.json()}")
JavaScript/Node.js
const FormData = require('form-data');
const fs = require('fs');
const axios = require('axios');
const form = new FormData();
form.append('image', fs.createReadStream('image.jpg'));
axios.post('https://api.iopaint.com/api/v1/remove-watermark', form, {
headers: {
'X-API-Key': process.env.IOPAINT_API_KEY,
...form.getHeaders()
},
responseType: 'arraybuffer'
})
.then(response => {
fs.writeFileSync('result.png', response.data);
console.log('✓ Success!');
})
.catch(error => {
console.error('✗ Error:', error.response?.status, error.response?.data);
});
PHP
<?php
$ch = curl_init('https://api.iopaint.com/api/v1/remove-watermark');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
'image' => new CURLFile('/path/to/image.jpg')
]);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'X-API-Key: your_api_key_here'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($httpCode == 200) {
file_put_contents('result.png', $result);
echo "✓ Success!\n";
} else {
echo "✗ Error: $httpCode\n";
}
?>
Go
package main
import (
"bytes"
"io"
"mime/multipart"
"net/http"
"os"
)
func main() {
body := &bytes.Buffer{}
writer := multipart.NewWriter(body)
// Add image file
file, _ := os.Open("image.jpg")
defer file.Close()
part, _ := writer.CreateFormFile("image", "image.jpg")
io.Copy(part, file)
writer.Close()
// Create request
req, _ := http.NewRequest("POST", "https://api.iopaint.com/api/v1/remove-watermark", body)
req.Header.Set("X-API-Key", os.Getenv("IOPAINT_API_KEY"))
req.Header.Set("Content-Type", writer.FormDataContentType())
// Send request
client := &http.Client{}
resp, _ := client.Do(req)
defer resp.Body.Close()
// Save result
out, _ := os.Create("result.png")
defer out.Close()
io.Copy(out, resp.Body)
}
2. Health Check
Check the API service status and availability.
Endpoint
GET /api/v1/health
Authentication
Not required.
Response
Success (200 OK)
{
"status": "healthy",
"model": "lama",
"device": "cuda",
"gpu_available": true
}
Response Fields:
| Field | Type | Description |
|---|---|---|
status |
string | Service status: healthy or unhealthy |
model |
string | Current AI model name |
device |
string | Compute device: cuda (GPU) or cpu |
gpu_available |
boolean | GPU availability |
Example
curl https://api.iopaint.com/api/v1/health
import requests
response = requests.get("https://api.iopaint.com/api/v1/health")
print(response.json())
# Output: {'status': 'healthy', 'model': 'lama', 'device': 'cuda', 'gpu_available': True}
3. Usage Statistics
Retrieve your account usage statistics.
Endpoint
GET /api/v1/stats
Authentication
Required. Include X-API-Key header.
Response
Success (200 OK)
{
"total": 1250,
"success": 1230,
"failed": 20,
"total_processing_time": 1845.5,
"avg_processing_time": 1.5
}
Response Fields:
| Field | Type | Description |
|---|---|---|
total |
integer | Total requests made |
success |
integer | Successful requests |
failed |
integer | Failed requests |
total_processing_time |
float | Cumulative processing time (seconds) |
avg_processing_time |
float | Average processing time (seconds) |
Example
curl https://api.iopaint.com/api/v1/stats \
-H "X-API-Key: $IOPAINT_API_KEY"
import requests
headers = {"X-API-Key": "your_api_key_here"}
response = requests.get("https://api.iopaint.com/api/v1/stats", headers=headers)
stats = response.json()
print(f"Total requests: {stats['total']}")
print(f"Success rate: {stats['success'] / stats['total'] * 100:.2f}%")
print(f"Average time: {stats['avg_processing_time']:.2f}s")
Models
LaMa (Current)
Large Mask Inpainting - Fast and efficient inpainting model.
| Property | Value |
|---|---|
| Name | lama |
| Speed | ⚡⚡⚡⚡⚡ (1-2s for 1024x1024) |
| Quality | ⭐⭐⭐⭐ |
| VRAM | ~1GB |
| Best For | Watermark removal, object removal |
Future Models (Coming Soon)
| Model | Speed | Quality | VRAM | Use Case |
|---|---|---|---|---|
| SD Inpainting | ⚡⚡⚡ | ⭐⭐⭐⭐⭐ | ~4GB | Creative editing |
| SDXL Inpainting | ⚡⚡ | ⭐⭐⭐⭐⭐ | ~8GB | Professional work |
Error Handling
Error Response Format
All errors return a JSON object with the following structure:
{
"error": "ErrorType",
"detail": "Human-readable error message",
"status_code": 400
}
HTTP Status Codes
| Code | Status | Description |
|---|---|---|
200 |
OK | Request successful |
400 |
Bad Request | Invalid request parameters |
401 |
Unauthorized | Missing or invalid API key |
413 |
Payload Too Large | File exceeds size limit |
429 |
Too Many Requests | Rate limit exceeded |
500 |
Internal Server Error | Server-side error |
503 |
Service Unavailable | Service temporarily unavailable |
Error Types
401 Unauthorized
Missing API Key:
{
"error": "Unauthorized",
"detail": "Missing API Key. Please provide X-API-Key header.",
"status_code": 401
}
Invalid API Key:
{
"error": "Unauthorized",
"detail": "Invalid API Key",
"status_code": 401
}
400 Bad Request
Invalid Image Format:
{
"error": "Bad Request",
"detail": "Invalid image format: cannot identify image file",
"status_code": 400
}
Image Too Large:
{
"error": "Bad Request",
"detail": "Image too large. Max dimension: 4096px",
"status_code": 400
}
File Too Large:
{
"error": "Bad Request",
"detail": "Image too large. Max size: 10MB",
"status_code": 400
}
429 Rate Limit Exceeded
{
"error": "Too Many Requests",
"detail": "Rate limit exceeded. Please try again later.",
"status_code": 429
}
Headers:
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1672531200
500 Internal Server Error
{
"error": "Internal Server Error",
"detail": "Processing failed: CUDA out of memory",
"status_code": 500
}
Error Handling Best Practices
import requests
import time
def remove_watermark_with_retry(image_path, max_retries=3):
"""Remove watermark with exponential backoff retry"""
url = "https://api.iopaint.com/api/v1/remove-watermark"
headers = {"X-API-Key": os.getenv("IOPAINT_API_KEY")}
for attempt in range(max_retries):
try:
with open(image_path, "rb") as f:
response = requests.post(
url,
headers=headers,
files={"image": f},
timeout=120
)
if response.status_code == 200:
return response.content
elif response.status_code == 429:
# Rate limit - exponential backoff
wait_time = 2 ** attempt
print(f"Rate limited. Waiting {wait_time}s...")
time.sleep(wait_time)
continue
elif response.status_code in [500, 503]:
# Server error - retry
if attempt < max_retries - 1:
time.sleep(2 ** attempt)
continue
else:
raise Exception(f"Server error: {response.json()}")
else:
# Client error - don't retry
raise Exception(f"Error {response.status_code}: {response.json()}")
except requests.Timeout:
if attempt < max_retries - 1:
print(f"Timeout. Retrying... ({attempt + 1}/{max_retries})")
continue
else:
raise
raise Exception("Max retries exceeded")
Rate Limiting
Rate Limit Rules
| Plan | Rate Limit | Burst | Quota |
|---|---|---|---|
| Free | 2 req/min | 5 | 10/day |
| Basic | 10 req/min | 20 | 3,000/month |
| Pro | 30 req/min | 60 | 20,000/month |
| Enterprise | Custom | Custom | Custom |
Rate Limit Headers
Every response includes rate limit information:
X-RateLimit-Limit: 10
X-RateLimit-Remaining: 7
X-RateLimit-Reset: 1672531200
| Header | Description |
|---|---|
X-RateLimit-Limit |
Maximum requests per time window |
X-RateLimit-Remaining |
Remaining requests in current window |
X-RateLimit-Reset |
Unix timestamp when limit resets |
Handling Rate Limits
import requests
import time
def wait_for_rate_limit_reset(response):
"""Wait until rate limit resets"""
if response.status_code == 429:
reset_time = int(response.headers.get('X-RateLimit-Reset', 0))
current_time = int(time.time())
wait_time = max(0, reset_time - current_time)
print(f"Rate limited. Waiting {wait_time}s for reset...")
time.sleep(wait_time + 1) # Add 1s buffer
return True
return False
Best Practices
- Check remaining quota before making requests
- Implement exponential backoff for retries
- Cache results to avoid duplicate requests
- Use batch endpoints (when available) for multiple images
- Upgrade your plan if consistently hitting limits
Best Practices
Performance Optimization
1. Image Preprocessing
from PIL import Image
def optimize_image(image_path, max_size=2048):
"""Resize large images before upload"""
img = Image.open(image_path)
# Check if resize needed
if max(img.size) > max_size:
ratio = max_size / max(img.size)
new_size = tuple(int(dim * ratio) for dim in img.size)
img = img.resize(new_size, Image.LANCZOS)
# Convert to RGB if needed
if img.mode != 'RGB':
img = img.convert('RGB')
# Save optimized
output = "optimized.jpg"
img.save(output, quality=95, optimize=True)
return output
2. Concurrent Processing
from concurrent.futures import ThreadPoolExecutor
import requests
def process_batch(image_paths, api_key, max_workers=4):
"""Process multiple images concurrently"""
def process_one(path):
headers = {"X-API-Key": api_key}
with open(path, "rb") as f:
response = requests.post(
"https://api.iopaint.com/api/v1/remove-watermark",
headers=headers,
files={"image": f}
)
return path, response
with ThreadPoolExecutor(max_workers=max_workers) as executor:
results = list(executor.map(process_one, image_paths))
return results
3. Connection Reuse
import requests
# Reuse session for multiple requests
session = requests.Session()
session.headers.update({"X-API-Key": api_key})
for image_path in image_paths:
with open(image_path, "rb") as f:
response = session.post(
"https://api.iopaint.com/api/v1/remove-watermark",
files={"image": f}
)
Security
Environment Variables
# .env file
IOPAINT_API_KEY=sk_live_1234567890abcdef
# .gitignore
.env
import os
from dotenv import load_dotenv
load_dotenv()
api_key = os.getenv("IOPAINT_API_KEY")
API Key Rotation
# Rotate keys periodically
def rotate_api_key():
old_key = os.getenv("IOPAINT_API_KEY")
new_key = generate_new_key() # From dashboard
# Test new key
test_response = requests.get(
"https://api.iopaint.com/api/v1/health",
headers={"X-API-Key": new_key}
)
if test_response.status_code == 200:
# Update environment
update_env("IOPAINT_API_KEY", new_key)
# Revoke old key from dashboard
revoke_key(old_key)
Cost Optimization
1. Cache Results
import hashlib
import os
def get_cached_result(image_path):
"""Check if result already cached"""
# Generate cache key from file content
with open(image_path, "rb") as f:
file_hash = hashlib.md5(f.read()).hexdigest()
cache_path = f"cache/{file_hash}.png"
if os.path.exists(cache_path):
return cache_path
return None
def process_with_cache(image_path, api_key):
"""Process with caching"""
# Check cache first
cached = get_cached_result(image_path)
if cached:
print(f"✓ Using cached result: {cached}")
return cached
# Process via API
result = remove_watermark(image_path, api_key)
# Save to cache
with open(image_path, "rb") as f:
file_hash = hashlib.md5(f.read()).hexdigest()
cache_path = f"cache/{file_hash}.png"
with open(cache_path, "wb") as f:
f.write(result)
return cache_path
2. Monitor Usage
def check_quota_before_request(api_key):
"""Check quota before making expensive requests"""
headers = {"X-API-Key": api_key}
response = requests.get(
"https://api.iopaint.com/api/v1/stats",
headers=headers
)
stats = response.json()
quota_used = stats['total']
plan_limit = 3000 # Basic plan
remaining = plan_limit - quota_used
if remaining < 100:
print(f"⚠️ Warning: Only {remaining} requests remaining!")
return remaining > 0
SDKs & Libraries
Official SDKs
Python
pip install iopaint-sdk
from iopaint import IOPaintClient
client = IOPaintClient(api_key="your_api_key")
# Simple usage
result = client.remove_watermark("image.jpg")
# With options
result = client.remove_watermark(
image="image.jpg",
mask="mask.png",
output="result.png"
)
# Batch processing
results = client.batch_process(
images=["img1.jpg", "img2.jpg"],
output_dir="./results"
)
JavaScript/TypeScript
npm install iopaint-sdk
const { IOPaintClient } = require('iopaint-sdk');
const client = new IOPaintClient({
apiKey: process.env.IOPAINT_API_KEY
});
// Simple usage
await client.removeWatermark('image.jpg', 'result.png');
// With mask
await client.removeWatermark('image.jpg', 'result.png', {
mask: 'mask.png'
});
Community Libraries
| Language | Library | Author |
|---|---|---|
| Go | iopaint-go |
Community |
| Ruby | iopaint-rb |
Community |
| Java | iopaint-java |
Community |
| PHP | iopaint-php |
Community |
Changelog
v1.0.0 (2025-11-28)
Initial Release
- ✨
/api/v1/remove-watermarkendpoint - ✨
/api/v1/healthendpoint - ✨
/api/v1/statsendpoint - ✨ API key authentication
- ✨ Rate limiting
- ✨ Support for JPEG, PNG, WebP
- ✨ Optional mask support
- ✨ Processing time metrics
Coming Soon
- 🔜
/api/v1/batch- Batch processing endpoint - 🔜
/api/v1/detect- Automatic watermark detection - 🔜 Webhook callbacks for async processing
- 🔜 Additional models (SD, SDXL)
- 🔜 Custom model training
Support
Resources
- API Status: status.iopaint.com
- Dashboard: iopaint.com/dashboard
- Documentation: docs.iopaint.com
- GitHub: github.com/let5sne/IOPaint
Contact
- Email: support@iopaint.com
- Discord: discord.gg/iopaint
- Issues: GitHub Issues
SLA (Service Level Agreement)
| Plan | Uptime | Support Response |
|---|---|---|
| Free | 95% | Community |
| Basic | 99% | 48 hours |
| Pro | 99.5% | 24 hours |
| Enterprise | 99.9% | 4 hours |
Legal
Terms of Service
By using the IOPaint API, you agree to our Terms of Service.
Privacy Policy
We respect your privacy. See our Privacy Policy.
Data Processing
- Images are processed in memory and not stored
- Uploaded images are deleted immediately after processing
- We do not train models on your data
- Logs contain only metadata (no image content)
Usage Restrictions
Allowed:
- ✅ Removing watermarks from your own content
- ✅ Restoring old photos
- ✅ Object removal for creative projects
- ✅ Commercial use (with appropriate plan)
Prohibited:
- ❌ Removing copyright protection
- ❌ Processing illegal content
- ❌ Violating third-party rights
- ❌ Automated scraping without permission
© 2025 IOPaint. All rights reserved.
Last updated: 2025-11-28