Getting Started
The FOTOhub API is a unified creative AI platform providing access to 80+ state-of-the-art AI models through a single, consistent interface. Generate images, create videos, compose music, run chat completions, analyze content, manage storage, and orchestrate compute workflows — all with one API key and one billing system.
Platform Overview
FOTOhub consolidates dozens of AI providers into a single REST API with unified authentication, billing, and response formats. Instead of managing separate accounts with multiple providers, you integrate once and gain access to everything.
Available Services
| Service | Description | Models |
|---|---|---|
| Image Generation | Text-to-image, image-to-image, inpainting | SeedDream, FLUX, Imagen 4, DALL-E, Grok Imagine |
| Video Generation | Text-to-video, image-to-video, video extension | Veo 3, Sora 2, Kling, WAN, Seedance, Hailuo |
| Music & Audio | Music generation, sound effects, audio-to-audio | IDA Music, MiniMax |
| 3D Generation | Image-to-3D, text-to-3D, GLB/OBJ/STL export | FH Lite 3D, FH Pro 3D |
| Chat & Text | Completions, reasoning, summarization | Claude, GPT-4o, Gemini, DeepSeek |
| Analysis & Vision | Image analysis, OCR, captioning | Multi-modal LLMs |
| Text-to-Speech | Voice synthesis, voice cloning | IDA Voice |
| Speech-to-Text | Transcription, translation | Whisper variants |
| Image Editing | Upscaling, background removal, style transfer | Specialized editing models |
| Storage & Compute | File management, agent workflows | Platform services |
Base URL
All API requests are made to the following base URL. Every endpoint is prefixed with /v1/ to ensure versioning compatibility.
https://apis.fotohub.app/v1/| Environment | URL |
|---|---|
| Production | https://apis.fotohub.app/v1/ |
| Console API | https://apis.fotohub.app/v1/console/ |
API Versioning
All current endpoints use the /v1/ prefix. When breaking changes are introduced, a new version prefix (e.g., /v2/) will be released. The previous version will remain available for at least 12 months after deprecation notice.
Prerequisites & Account Setup
Before making your first API call, you need a FOTOhub account, an API key, and a funded USD wallet.
1. Creating an Account
Navigate to fotohub.app and sign up. You can use Google, GitHub, or an email address.
2. Generating an API Key
Go to the Developer Console -> Keys. Click 'Create New Key'.
Secure your key
Your API key (fh_live_*) grants access to your USD wallet. Never expose it in client-side code.
Understanding Key Types
FOTOhub provides two types of keys:
- Test Keys (
fh_test_...): Used for sandbox environments. They do not charge your USD wallet but are limited in rate and model access. - Live Keys (
fh_live_...): Production keys that bill directly to your USD wallet.
SDK Installation for All Languages
We provide official SDKs for Python, TypeScript, Go, and a CLI tool.
pip install fotohub
python -c "import fotohub; print(fotohub.__version__)"npm install fotohub
npx fotohub --versiongo get github.com/fotohub/fotohub-gocomposer require fotohub/fotohub-phpYour First 10 API Calls
Let's walk through 10 essential API operations to familiarize you with the platform.
1. Image Generation
Endpoint: POST /v1/ai/generate/image (Cost approx $0.025)
import requests
res = requests.post(
'https://apis.fotohub.app/v1/ai/generate/image',
headers={'Authorization': 'Bearer fh_live_your_api_key'},
json={"model": "seedream-5-0", "prompt": "cat"}
)
print(res.json())const res = await fetch('https://apis.fotohub.app/v1/ai/generate/image', {
method: 'POST',
headers: { 'Authorization': 'Bearer fh_live_your_api_key', 'Content-Type': 'application/json' },
body: JSON.stringify({"model": "seedream-5-0", "prompt": "cat"})
});
console.log(await res.json());// Go implementation for 1. Image Generation
req, _ := http.NewRequest("POST", "https://apis.fotohub.app/v1/ai/generate/image", bytes.NewBuffer([]byte(`{"model": "seedream-5-0", "prompt": "cat"}`)));
req.Header.Set("Authorization", "Bearer fh_live_your_api_key");
req.Header.Set("Content-Type", "application/json");
client := &http.Client{}
resp, _ := client.Do(req)curl -X POST https://apis.fotohub.app/v1/ai/generate/image \
-H 'Authorization: Bearer fh_live_your_api_key' \
-H 'Content-Type: application/json' \
-d '{"model": "seedream-5-0", "prompt": "cat"}'2. Video Generation
Endpoint: POST /v1/ai/generate/video (Cost approx $0.150)
import requests
res = requests.post(
'https://apis.fotohub.app/v1/ai/generate/video',
headers={'Authorization': 'Bearer fh_live_your_api_key'},
json={"model": "kling-1-5", "prompt": "dog running"}
)
print(res.json())const res = await fetch('https://apis.fotohub.app/v1/ai/generate/video', {
method: 'POST',
headers: { 'Authorization': 'Bearer fh_live_your_api_key', 'Content-Type': 'application/json' },
body: JSON.stringify({"model": "kling-1-5", "prompt": "dog running"})
});
console.log(await res.json());// Go implementation for 2. Video Generation
req, _ := http.NewRequest("POST", "https://apis.fotohub.app/v1/ai/generate/video", bytes.NewBuffer([]byte(`{"model": "kling-1-5", "prompt": "dog running"}`)));
req.Header.Set("Authorization", "Bearer fh_live_your_api_key");
req.Header.Set("Content-Type", "application/json");
client := &http.Client{}
resp, _ := client.Do(req)curl -X POST https://apis.fotohub.app/v1/ai/generate/video \
-H 'Authorization: Bearer fh_live_your_api_key' \
-H 'Content-Type: application/json' \
-d '{"model": "kling-1-5", "prompt": "dog running"}'3. Chat Completion
Endpoint: POST /v1/ai/chat/completions (Cost approx $0.005)
import requests
res = requests.post(
'https://apis.fotohub.app/v1/ai/chat/completions',
headers={'Authorization': 'Bearer fh_live_your_api_key'},
json={"model": "gpt-4o", "messages": [{"role": "user", "content": "hello"}]}
)
print(res.json())const res = await fetch('https://apis.fotohub.app/v1/ai/chat/completions', {
method: 'POST',
headers: { 'Authorization': 'Bearer fh_live_your_api_key', 'Content-Type': 'application/json' },
body: JSON.stringify({"model": "gpt-4o", "messages": [{"role": "user", "content": "hello"}]})
});
console.log(await res.json());// Go implementation for 3. Chat Completion
req, _ := http.NewRequest("POST", "https://apis.fotohub.app/v1/ai/chat/completions", bytes.NewBuffer([]byte(`{"model": "gpt-4o", "messages": [{"role": "user", "content": "hello"}]}`)));
req.Header.Set("Authorization", "Bearer fh_live_your_api_key");
req.Header.Set("Content-Type", "application/json");
client := &http.Client{}
resp, _ := client.Do(req)curl -X POST https://apis.fotohub.app/v1/ai/chat/completions \
-H 'Authorization: Bearer fh_live_your_api_key' \
-H 'Content-Type: application/json' \
-d '{"model": "gpt-4o", "messages": [{"role": "user", "content": "hello"}]}'4. Text-to-Speech
Endpoint: POST /v1/ai/audio/speech (Cost approx $0.015)
import requests
res = requests.post(
'https://apis.fotohub.app/v1/ai/audio/speech',
headers={'Authorization': 'Bearer fh_live_your_api_key'},
json={"model": "ida-voice", "input": "Hello world", "voice": "alloy"}
)
print(res.json())const res = await fetch('https://apis.fotohub.app/v1/ai/audio/speech', {
method: 'POST',
headers: { 'Authorization': 'Bearer fh_live_your_api_key', 'Content-Type': 'application/json' },
body: JSON.stringify({"model": "ida-voice", "input": "Hello world", "voice": "alloy"})
});
console.log(await res.json());// Go implementation for 4. Text-to-Speech
req, _ := http.NewRequest("POST", "https://apis.fotohub.app/v1/ai/audio/speech", bytes.NewBuffer([]byte(`{"model": "ida-voice", "input": "Hello world", "voice": "alloy"}`)));
req.Header.Set("Authorization", "Bearer fh_live_your_api_key");
req.Header.Set("Content-Type", "application/json");
client := &http.Client{}
resp, _ := client.Do(req)curl -X POST https://apis.fotohub.app/v1/ai/audio/speech \
-H 'Authorization: Bearer fh_live_your_api_key' \
-H 'Content-Type: application/json' \
-d '{"model": "ida-voice", "input": "Hello world", "voice": "alloy"}'5. Background Removal
Endpoint: POST /v1/ai/edit/remove-background (Cost approx $0.010)
import requests
res = requests.post(
'https://apis.fotohub.app/v1/ai/edit/remove-background',
headers={'Authorization': 'Bearer fh_live_your_api_key'},
json={"image_url": "https://example.com/cat.jpg"}
)
print(res.json())const res = await fetch('https://apis.fotohub.app/v1/ai/edit/remove-background', {
method: 'POST',
headers: { 'Authorization': 'Bearer fh_live_your_api_key', 'Content-Type': 'application/json' },
body: JSON.stringify({"image_url": "https://example.com/cat.jpg"})
});
console.log(await res.json());// Go implementation for 5. Background Removal
req, _ := http.NewRequest("POST", "https://apis.fotohub.app/v1/ai/edit/remove-background", bytes.NewBuffer([]byte(`{"image_url": "https://example.com/cat.jpg"}`)));
req.Header.Set("Authorization", "Bearer fh_live_your_api_key");
req.Header.Set("Content-Type", "application/json");
client := &http.Client{}
resp, _ := client.Do(req)curl -X POST https://apis.fotohub.app/v1/ai/edit/remove-background \
-H 'Authorization: Bearer fh_live_your_api_key' \
-H 'Content-Type: application/json' \
-d '{"image_url": "https://example.com/cat.jpg"}'6. OCR
Endpoint: POST /v1/ai/vision/ocr (Cost approx $0.005)
import requests
res = requests.post(
'https://apis.fotohub.app/v1/ai/vision/ocr',
headers={'Authorization': 'Bearer fh_live_your_api_key'},
json={"image_url": "https://example.com/receipt.jpg"}
)
print(res.json())const res = await fetch('https://apis.fotohub.app/v1/ai/vision/ocr', {
method: 'POST',
headers: { 'Authorization': 'Bearer fh_live_your_api_key', 'Content-Type': 'application/json' },
body: JSON.stringify({"image_url": "https://example.com/receipt.jpg"})
});
console.log(await res.json());// Go implementation for 6. OCR
req, _ := http.NewRequest("POST", "https://apis.fotohub.app/v1/ai/vision/ocr", bytes.NewBuffer([]byte(`{"image_url": "https://example.com/receipt.jpg"}`)));
req.Header.Set("Authorization", "Bearer fh_live_your_api_key");
req.Header.Set("Content-Type", "application/json");
client := &http.Client{}
resp, _ := client.Do(req)curl -X POST https://apis.fotohub.app/v1/ai/vision/ocr \
-H 'Authorization: Bearer fh_live_your_api_key' \
-H 'Content-Type: application/json' \
-d '{"image_url": "https://example.com/receipt.jpg"}'7. 3D Generation
Endpoint: POST /v1/ai/generate/3d (Cost approx $0.500)
import requests
res = requests.post(
'https://apis.fotohub.app/v1/ai/generate/3d',
headers={'Authorization': 'Bearer fh_live_your_api_key'},
json={"image_url": "https://example.com/object.jpg", "format": "glb"}
)
print(res.json())const res = await fetch('https://apis.fotohub.app/v1/ai/generate/3d', {
method: 'POST',
headers: { 'Authorization': 'Bearer fh_live_your_api_key', 'Content-Type': 'application/json' },
body: JSON.stringify({"image_url": "https://example.com/object.jpg", "format": "glb"})
});
console.log(await res.json());// Go implementation for 7. 3D Generation
req, _ := http.NewRequest("POST", "https://apis.fotohub.app/v1/ai/generate/3d", bytes.NewBuffer([]byte(`{"image_url": "https://example.com/object.jpg", "format": "glb"}`)));
req.Header.Set("Authorization", "Bearer fh_live_your_api_key");
req.Header.Set("Content-Type", "application/json");
client := &http.Client{}
resp, _ := client.Do(req)curl -X POST https://apis.fotohub.app/v1/ai/generate/3d \
-H 'Authorization: Bearer fh_live_your_api_key' \
-H 'Content-Type: application/json' \
-d '{"image_url": "https://example.com/object.jpg", "format": "glb"}'8. Translation
Endpoint: POST /v1/ai/text/translate (Cost approx $0.001)
import requests
res = requests.post(
'https://apis.fotohub.app/v1/ai/text/translate',
headers={'Authorization': 'Bearer fh_live_your_api_key'},
json={"text": "Hello", "target": "es"}
)
print(res.json())const res = await fetch('https://apis.fotohub.app/v1/ai/text/translate', {
method: 'POST',
headers: { 'Authorization': 'Bearer fh_live_your_api_key', 'Content-Type': 'application/json' },
body: JSON.stringify({"text": "Hello", "target": "es"})
});
console.log(await res.json());// Go implementation for 8. Translation
req, _ := http.NewRequest("POST", "https://apis.fotohub.app/v1/ai/text/translate", bytes.NewBuffer([]byte(`{"text": "Hello", "target": "es"}`)));
req.Header.Set("Authorization", "Bearer fh_live_your_api_key");
req.Header.Set("Content-Type", "application/json");
client := &http.Client{}
resp, _ := client.Do(req)curl -X POST https://apis.fotohub.app/v1/ai/text/translate \
-H 'Authorization: Bearer fh_live_your_api_key' \
-H 'Content-Type: application/json' \
-d '{"text": "Hello", "target": "es"}'9. Webhooks Registration
Endpoint: POST /v1/webhooks/register (Cost approx $0.000)
import requests
res = requests.post(
'https://apis.fotohub.app/v1/webhooks/register',
headers={'Authorization': 'Bearer fh_live_your_api_key'},
json={"url": "https://my.app/webhook", "events": ["job.completed"]}
)
print(res.json())const res = await fetch('https://apis.fotohub.app/v1/webhooks/register', {
method: 'POST',
headers: { 'Authorization': 'Bearer fh_live_your_api_key', 'Content-Type': 'application/json' },
body: JSON.stringify({"url": "https://my.app/webhook", "events": ["job.completed"]})
});
console.log(await res.json());// Go implementation for 9. Webhooks Registration
req, _ := http.NewRequest("POST", "https://apis.fotohub.app/v1/webhooks/register", bytes.NewBuffer([]byte(`{"url": "https://my.app/webhook", "events": ["job.completed"]}`)));
req.Header.Set("Authorization", "Bearer fh_live_your_api_key");
req.Header.Set("Content-Type", "application/json");
client := &http.Client{}
resp, _ := client.Do(req)curl -X POST https://apis.fotohub.app/v1/webhooks/register \
-H 'Authorization: Bearer fh_live_your_api_key' \
-H 'Content-Type: application/json' \
-d '{"url": "https://my.app/webhook", "events": ["job.completed"]}'10. Balance Check
Endpoint: POST /v1/billing/balance (Cost approx $0.000)
import requests
res = requests.post(
'https://apis.fotohub.app/v1/billing/balance',
headers={'Authorization': 'Bearer fh_live_your_api_key'},
json={}
)
print(res.json())const res = await fetch('https://apis.fotohub.app/v1/billing/balance', {
method: 'POST',
headers: { 'Authorization': 'Bearer fh_live_your_api_key', 'Content-Type': 'application/json' },
body: JSON.stringify({})
});
console.log(await res.json());// Go implementation for 10. Balance Check
req, _ := http.NewRequest("POST", "https://apis.fotohub.app/v1/billing/balance", bytes.NewBuffer([]byte(`{}`)));
req.Header.Set("Authorization", "Bearer fh_live_your_api_key");
req.Header.Set("Content-Type", "application/json");
client := &http.Client{}
resp, _ := client.Do(req)curl -X POST https://apis.fotohub.app/v1/billing/balance \
-H 'Authorization: Bearer fh_live_your_api_key' \
-H 'Content-Type: application/json' \
-d '{}'Understanding Async Jobs
Many operations (like video and 3D generation) are asynchronous. You submit a job, get a 202 Accepted, and then poll or receive a webhook.
sequenceDiagram
Client->>FOTOhub API: POST /v1/ai/generate/video
FOTOhub API-->>Client: 202 Accepted (job_id: vid_123)
loop Polling (Every 3s)
Client->>FOTOhub API: GET /v1/jobs/vid_123
FOTOhub API-->>Client: 200 OK (status: processing)
end
Client->>FOTOhub API: GET /v1/jobs/vid_123
FOTOhub API-->>Client: 200 OK (status: completed, url: ...)Webhook Quick Setup
Avoid polling by setting up webhooks. Register an endpoint to receive POST requests when jobs complete.
1. Start ngrok
ngrok http 30002. Register webhook
import hmac
import hashlib
def verify_webhook(payload, signature, secret):
expected = hmac.new(secret.encode(), payload.encode(), hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature)import crypto from 'crypto';
function verifyWebhook(payload: string, signature: string, secret: string) {
const expected = crypto.createHmac('sha256', secret).update(payload).digest('hex');
return crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}// Go implementation of HMAC-SHA256# Webhook registration curlUSD Wallet & Billing
The FOTOhub API operates strictly on a prepaid USD wallet. We never use credits, token packs, PLN, or zł. All transactions, balances, and charges are denominated in US Dollars (USD).
Minimum Top-up
The minimum top-up amount is $10.00 USD. You can set up auto-recharge when your balance falls below a threshold.
Transaction History
Every API call returns a billing block in the response JSON:
{
"billing": {
"cost_usd": 0.025,
"balance_usd": 99.975,
"currency": "USD"
}
}Rate Limits Overview
| Tier | Requests/Minute | Concurrent Jobs |
|---|---|---|
| Basic | 30 | 3 |
| Standard | 120 | 10 |
| Pro | 500 | 50 |
When you exceed your limit, you will receive a 429 Too Many Requests status code along with a Retry-After header. |
Error Handling Fundamentals
| Status | Code | Description |
|---|---|---|
| 401 | unauthorized | Invalid or missing API key |
| 402 | payment_required | Insufficient USD balance |
| 429 | rate_limit_exceeded | Too many requests |
| 503 | service_unavailable | Model is currently down or overloaded |
DLQ & Retry Patterns
We recommend implementing an exponential backoff strategy for 429 and 503 errors.
Production Checklist
- API Key Security: Use environment variables (
FOTOHUB_API_KEY) and secret managers (AWS Secrets Manager, Vault, Doppler). Never commit keys or expose them in browser bundles. - Prepaid USD Balance Buffer: Maintain an active reserve in your USD wallet (
wallet.available_usd) and configure programmatic balance monitoring to avoid402 INSUFFICIENT_FUNDSinterruptions. - Cryptographic Webhook Verification: Implement HMAC-SHA256 signature verification (
X-FotoHub-Signature) with timestamp checking (within 300s window) to reject replay attacks. - Idempotency Keys: Attach unique
idempotency_key(UUIDv4) headers to all generation and mutation requests to safeguard against duplicate charges during network retries. - Circuit Breakers & Exponential Backoff: Implement exponential backoff with full jitter for transient
429 RATE_LIMIT_EXCEEDEDand503 MODEL_OVERLOADEDresponses. - Dead-Letter Queue (DLQ): Buffer incoming webhook events to Redis/RabbitMQ/SQS and route failed events to a DLQ for diagnostics and replay.
- Timeout Budgets: Configure per-service timeout budgets (e.g., 30s for sync images, 300s for polling async video/3D tasks).
- BYOB Destination Setup: Configure S3/Cloudflare R2 external destinations via
/v1/destinationsto avoid secondary downloads and egress fees. - Graceful Degradation: Fall back to secondary models (e.g., Seedream 5.0 to FLUX 2 or Gemini Flash) when primary endpoints experience localized queue spikes.
- Structured Logging & Telemetry: Log
request_id,usd_charged, andlatency_mswithout logging sensitive customer prompt data or PII. - Content Moderation Pre-Flight: Run basic prompt compliance checks locally before dispatching to avoid avoidable 400 validation rejects.
- Region & Network Latency: Benchmark latency against
eu-central-1(Frankfurt) and consider peering or co-locating compute workloads. - Rate Limit Concurrency: Monitor active concurrent jobs and distribute batch jobs with semaphore-bounded worker pools.
- Output Container Validation: Always verify content types and download assets immediately or sync them to persistent cloud storage.
- Health Checks & Uptime Monitoring: Subscribe to status.fotohub.app webhooks for real-time cluster incident updates.
Next Steps
- Image Generation — Generate photorealistic imagery with FLUX.1, Seedream 5.0, and Imagen 3.
- Video Generation — Create cinematic clips using Seedance 2.0 Pro and Kling v2.1.
- Chat & LLM — Integrate Claude 3.5 Sonnet, DeepSeek V3, and Gemini 2.0 with tool calling.
- Audio & Speech — Synthesize background scores, Foley sound effects, and multilingual TTS.
- 3D Generation — Convert 2D photos into watertight textured GLB and Apple AR USDZ meshes.
- Cloud Compute — Provision dedicated NVIDIA A10G/T4 GPU instances and Firecracker sandboxes.
- Multimodal Recipes — Explore 11 end-to-end production automation blueprints.

