- Image IA — Retouchez et modifiez vos photos avec l'intelligence artificielle (15s par génération)
- Vidéo IA - Motion Control Pro — Transférez les mouvements d'une vidéo vers votre personnage (60s par génération)
- Création de Vidéo — Générez des vidéos de 4s ou 8s à partir d'un prompt texte (60s par génération)
- Musique IA — Créez des morceaux originaux avec paroles en 30 secondes
- Haute qualité — Résolutions professionnelles pour tous vos contenus
- Historique 48h — Vos générations sont sauvegardées automatiquement pendant 48 heures
- API disponible — Intégrez nos outils dans vos propres applications
- Qualité professionnelle — Résultats réalistes grâce à nos modèles IA de dernière génération
- Simplicité — Interface intuitive, aucune compétence technique requise
- Flexibilité — Système de crédits sans engagement, payez uniquement ce que vous utilisez
- Confidentialité — Vos fichiers sont supprimés automatiquement après 24h
- Support réactif — Équipe disponible pour vous aider en cas de besoin
Créez votre compte gratuitement et commencez à générer vos premiers contenus IA en quelques secondes.
Image IA vous permet de transformer vos photos grâce à des prompts textuels. L'IA analyse votre image et applique les modifications demandées de manière intelligente et réaliste.
- "Remove background and make it transparent"
- "Change the sky to sunset colors"
- "Add professional studio lighting"
- "Remove all blemishes and imperfections"
- "Change eye color to blue"
- "Make the image look like a painting"
- Formats — JPG, PNG, WebP
- Taille maximale — 10 MB
- Résolution recommandée — Minimum 512x512 pixels pour des résultats optimaux
- Qualité — Images nettes et bien éclairées donnent les meilleurs résultats
Coût : 1 crédit ⭐ par image générée
Temps de traitement : ~15 secondes
Motion Control Pro analyse une vidéo source et transfère ses mouvements (gestes, expressions faciales, danses, animations) vers le personnage de votre image. Vous pouvez également utiliser un prompt pour préciser le type de transfert souhaité.
- Transfert de visage — Remplacez le visage d'une vidéo par celui de votre image
- Animation de personnage — Donnez vie à un portrait statique avec des mouvements réalistes
- Transfert de danse — Faites danser votre personnage en copiant les mouvements d'un danseur
- Expressions faciales — Transférez des émotions et expressions depuis une vidéo
- Synchronisation labiale — Faites parler votre personnage en synchronisant les lèvres
- Formats — JPG, PNG, WebP
- Taille maximale — 10 MB
- Cadrage — Personnage bien visible et centré dans l'image
- Formats — MP4, MOV, WebM
- Taille maximale — 100 MB
- Qualité — Mouvements clairs et bien visibles pour un meilleur transfert
Coût : 3 crédits ⭐ par vidéo générée
Temps de traitement : ~60 secondes
Notre IA de génération vidéo transforme vos prompts textuels en vidéos haute définition. Décrivez la scène que vous imaginez, et l'IA crée un contenu vidéo cohérent et réaliste.
- "A serene mountain lake at sunrise, camera slowly panning across the water, birds flying in the distance"
- "Neon-lit Tokyo street at night, rain falling, people with umbrellas walking, camera tracking motion"
- "Close-up of a steaming cup of coffee, steam rising, soft morning light through window"
- "Astronaut floating in space, Earth visible in background, slow rotation, cinematic 4K"
- "Wildflower meadow, gentle breeze, butterflies, golden hour lighting, drone shot descending"
- "Vintage car driving on coastal highway, sunset colors, waves crashing on rocks below"
- Soyez spécifique — Décrivez précisément l'action, l'ambiance, les couleurs, la lumière
- Indiquez le mouvement — Précisez les mouvements de caméra (pan, zoom, tracking, drone shot)
- Mentionnez le style — Ajoutez des termes comme "cinematic", "4K", "realistic", "dreamy"
- Gardez une cohérence — Décrivez une scène unique et cohérente plutôt que plusieurs actions
- Testez en 4s d'abord — Commencez par une version courte avant d'investir dans 8 secondes
| Durée | Coût | Temps de traitement |
|---|---|---|
| 4 secondes | 3 crédits ⭐ | ~60 secondes |
| 8 secondes | 6 crédits ⭐ | ~60 secondes |
- Formats disponibles — Vertical (720 × 1280) ou Horizontal (1280 × 720)
- Résolution — 720p HD
- Format fichier — MP4 (H.264)
- Framerate — 24 fps
- Ratios d'aspect — 9:16 (Vertical) ou 16:9 (Horizontal)
Musique IA utilise des modèles d'intelligence artificielle avancés pour composer des morceaux originaux basés sur votre description. L'IA génère à la fois la musique instrumentale ET les paroles, créant une chanson complète prête à l'emploi.
- Pop énergique — "Upbeat pop song, catchy melody, electronic drums, synthesizers, 128 BPM"
- Ballade mélancolique — "Sad piano ballad, emotional, slow tempo, strings in background, minor key"
- Rock énergique — "Heavy rock song, electric guitars, powerful drums, energetic, 140 BPM"
- Electro dansante — "EDM track, festival vibes, big drop, synthesizers, bass heavy, 130 BPM"
- Acoustique doux — "Soft acoustic guitar, intimate, calm, folk style, warm atmosphere"
- Hip-Hop moderne — "Hip-hop beat, trap style, 808 bass, hi-hats, modern production, 85 BPM"
Vous pouvez structurer vos paroles comme vous le souhaitez. Voici un exemple :
[Verse 1] Walking down the street at night City lights are shining bright Feeling free, feeling alive This is where my dreams survive [Chorus] We're dancing in the moonlight Everything feels so right Let the music take control Feel it deep within your soul [Verse 2] Hearts are beating to the sound Magic happens all around In this moment we belong Living life just like a song
- Précisez le tempo — Indiquez les BPM pour un rythme spécifique (70 BPM = lent, 140 BPM = rapide)
- Mentionnez les instruments — Piano, guitare, batterie, violon, synthés, etc.
- Décrivez l'ambiance — Joyeux, mélancolique, énergique, calme, mystérieux
- Spécifiez le genre — Pop, Rock, EDM, Hip-Hop, Jazz, Classical, Country
- Structurez les lyrics — Utilisez [Verse], [Chorus], [Bridge] pour guider la composition
Coût : 1 crédit ⭐ par génération musicale
Temps de traitement : ~30 secondes
- Format — MP3 (320 kbps haute qualité)
- Fréquence d'échantillonnage — 44.1 kHz (qualité CD)
- Durée — Variable selon les lyrics (généralement 60-120 secondes)
- Voix — Voix synthétique masculine ou féminine selon le style
- Protocol — HTTPS uniquement (TLS 1.3)
- Format — JSON avec UTF-8 encoding
- Versioning — Version dans l'URL (/v1/, /v2/)
- Authentication — Bearer token (API Key)
- Rate Limiting — Headers X-RateLimit-* dans chaque réponse
- Idempotence — POST avec Idempotency-Key pour éviter les doublons
- Webhooks — Callbacks HTTPS avec signatures HMAC-SHA256
https://api.yourdomain.com/v1
https://eu.api.yourdomain.com/v1
https://us.api.yourdomain.com/v1
Toutes les requêtes nécessitent une clé API dans le header Authorization avec le préfixe Bearer.
curl https://api.yourdomain.com/v1/credits \ -H "Authorization: Bearer sk_live_abc123..."
| Endpoint | Méthode | Description | Async |
|---|---|---|---|
| /v1/imageai | POST | Retouche et modification d'images | ✅ |
| /v1/videoai | POST | Transfert de mouvements vidéo | ✅ |
| /v1/text2video | POST | Génération vidéo depuis texte | ✅ |
| /v1/musicai | POST | Composition musicale IA | ✅ |
| /v1/jobs/{id} | GET | Statut d'une tâche asynchrone | - |
| /v1/jobs/{id}/cancel | POST | Annuler une tâche en cours | - |
| /v1/credits | GET | Solde de crédits disponibles | - |
| /v1/webhooks | GET/POST/DELETE | Gestion des webhooks | - |
Tous les endpoints de génération (Image IA, Vidéo IA, etc.) fonctionnent en mode asynchrone. Vous recevez immédiatement un job_id que vous pouvez poll ou recevoir via webhook.
POST /v1/imageai
Content-Type: multipart/form-data
{
"image": [binary],
"prompt": "Remove background",
"webhook_url": "https://yourapp.com/webhooks/metaborg"
}
Response 202 Accepted:
{
"job_id": "job_abc123xyz",
"status": "queued",
"created_at": "2025-01-24T10:30:00Z",
"estimated_time": 15
}
GET /v1/jobs/job_abc123xyz
Response 200 OK:
{
"job_id": "job_abc123xyz",
"status": "processing",
"progress": 0.65,
"created_at": "2025-01-24T10:30:00Z",
"started_at": "2025-01-24T10:30:02Z"
}
GET /v1/jobs/job_abc123xyz
Response 200 OK:
{
"job_id": "job_abc123xyz",
"status": "completed",
"result": {
"url": "https://cdn.metaborg.app/results/xyz.png",
"expires_at": "2025-01-31T10:30:00Z",
"size_bytes": 2456789,
"width": 1024,
"height": 768,
"format": "png"
},
"credits_used": 1,
"processing_time_ms": 12450,
"completed_at": "2025-01-24T10:30:15Z"
}
Au lieu de poll le statut, configurez un webhook pour recevoir une notification quand la tâche est terminée. Plus efficace et réduit les appels API.
{
"url": "https://yourapp.com/webhooks/metaborg",
"events": ["job.completed", "job.failed"],
"secret": "whsec_abc123..." // Pour vérifier la signature
}
Response 201 Created:
{
"webhook_id": "wh_xyz789",
"url": "https://yourapp.com/webhooks/metaborg",
"events": ["job.completed", "job.failed"],
"created_at": "2025-01-24T10:30:00Z"
}
POST https://yourapp.com/webhooks/metaborg
Content-Type: application/json
X-Metaborg-Signature: sha256=abc123...
X-Metaborg-Event: job.completed
{
"event": "job.completed",
"timestamp": "2025-01-24T10:30:15Z",
"data": {
"job_id": "job_abc123xyz",
"status": "completed",
"result": {
"url": "https://cdn.metaborg.app/results/xyz.png",
"expires_at": "2025-01-31T10:30:00Z"
},
"credits_used": 1
}
}
const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const hmac = crypto.createHmac('sha256', secret);
const digest = 'sha256=' + hmac.update(payload).digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(digest)
);
}
app.post('/webhooks/metaborg', (req, res) => {
const signature = req.headers['x-metaborg-signature'];
const payload = JSON.stringify(req.body);
if (!verifyWebhook(payload, signature, WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Traiter l'événement
const { event, data } = req.body;
if (event === 'job.completed') {
console.log('Job completed:', data.job_id);
// Télécharger le résultat, notifier l'utilisateur, etc.
}
res.status(200).send('OK');
});
Pour éviter les doublons en cas de retry réseau, utilisez le header Idempotency-Key (UUID v4 recommandé).
curl -X POST https://api.yourdomain.com/v1/imageai \ -H "Authorization: Bearer sk_live_..." \ -H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \ -F "image=@photo.jpg"
Si vous envoyez la même requête avec la même Idempotency-Key dans les 24h, vous recevrez le job_id original au lieu de créer un nouveau job.
Chaque réponse inclut des headers indiquant votre quota :
X-RateLimit-Limit: 60 # Requêtes max par minute X-RateLimit-Remaining: 42 # Requêtes restantes X-RateLimit-Reset: 1706089200 # Timestamp de reset (Unix) Retry-After: 18 # Secondes avant retry (si 429)
import time
import requests
def api_call_with_retry(url, max_retries=5):
for attempt in range(max_retries):
response = requests.get(url, headers={'Authorization': f'Bearer {API_KEY}'})
if response.status_code == 200:
return response.json()
if response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 60))
wait_time = min(retry_after * (2 ** attempt), 300) # Max 5 min
print(f"Rate limited. Waiting {wait_time}s...")
time.sleep(wait_time)
continue
response.raise_for_status()
raise Exception('Max retries exceeded')
| Code | Status | Description |
|---|---|---|
| 200 | OK | Requête réussie |
| 201 | Created | Ressource créée (webhook, etc.) |
| 202 | Accepted | Tâche acceptée (traitement asynchrone) |
| 400 | Bad Request | Paramètres invalides ou manquants |
| 401 | Unauthorized | Clé API invalide ou manquante |
| 402 | Payment Required | Crédits insuffisants |
| 404 | Not Found | Ressource introuvable (job_id inexistant) |
| 413 | Payload Too Large | Fichier trop volumineux |
| 415 | Unsupported Media Type | Format de fichier non supporté |
| 422 | Unprocessable Entity | Validation échouée (détails dans body) |
| 429 | Too Many Requests | Rate limit dépassé |
| 500 | Internal Server Error | Erreur serveur (contactez support si persistant) |
| 503 | Service Unavailable | Maintenance en cours (voir status.metaborg.app) |
{
"error": {
"code": "insufficient_credits",
"message": "You don't have enough credits for this operation",
"details": {
"required": 3,
"available": 1
},
"request_id": "req_abc123xyz",
"documentation_url": "https://docs.metaborg.app/errors/insufficient_credits"
}
}
Les endpoints qui retournent des listes (historique de jobs, webhooks) supportent la pagination cursor-based.
{
"data": [ /* 50 jobs */ ],
"pagination": {
"next_cursor": "cur_xyz789",
"has_more": true
}
}
// Page suivante
GET /v1/jobs?limit=50&cursor=cur_xyz789
Notre API complète est documentée au format OpenAPI 3.0. Importez-la dans Postman, Insomnia, ou générez des SDKs.
https://api.yourdomain.com/openapi.json
npm install axios form-data dotenv # Pour TypeScript npm install --save-dev @types/node @types/axios
import axios, { AxiosInstance, AxiosError } from 'axios';
import FormData from 'form-data';
import fs from 'fs';
import crypto from 'crypto';
interface MetaborgConfig {
apiKey: string;
baseURL?: string;
timeout?: number;
maxRetries?: number;
}
interface JobResponse {
job_id: string;
status: 'queued' | 'processing' | 'completed' | 'failed';
result?: {
url: string;
expires_at: string;
};
error?: string;
credits_used?: number;
}
class MetaborgClient {
private client: AxiosInstance;
private maxRetries: number;
constructor(config: MetaborgConfig) {
this.maxRetries = config.maxRetries || 3;
this.client = axios.create({
baseURL: config.baseURL || 'https://api.yourdomain.com/v1',
timeout: config.timeout || 30000,
headers: {
'Authorization': `Bearer ${config.apiKey}`,
'User-Agent': 'MetaborgClient/1.0'
}
});
// Interceptor pour retry automatique
this.client.interceptors.response.use(
response => response,
async (error: AxiosError) => {
const config = error.config;
if (!config || !config.headers) return Promise.reject(error);
// Retry sur 429 (Rate Limit)
if (error.response?.status === 429) {
const retryAfter = parseInt(error.response.headers['retry-after'] || '60');
const attempt = (config as any).__retryCount || 0;
if (attempt < this.maxRetries) {
(config as any).__retryCount = attempt + 1;
await this.sleep(retryAfter * 1000);
return this.client.request(config);
}
}
// Retry sur 5xx (Erreur serveur)
if (error.response && error.response.status >= 500) {
const attempt = (config as any).__retryCount || 0;
if (attempt < this.maxRetries) {
(config as any).__retryCount = attempt + 1;
const delay = Math.min(1000 * Math.pow(2, attempt), 10000);
await this.sleep(delay);
return this.client.request(config);
}
}
return Promise.reject(error);
}
);
}
private sleep(ms: number): Promise {
return new Promise(resolve => setTimeout(resolve, ms));
}
private generateIdempotencyKey(): string {
return crypto.randomUUID();
}
/**
* Image IA - Retouche et modification d'images
*/
async processImage(
imagePath: string,
options: {
prompt?: string;
webhook_url?: string;
idempotency_key?: string;
} = {}
): Promise {
const form = new FormData();
form.append('image', fs.createReadStream(imagePath));
if (options.prompt) form.append('prompt', options.prompt);
if (options.webhook_url) form.append('webhook_url', options.webhook_url);
const response = await this.client.post('/imageai', form, {
headers: {
...form.getHeaders(),
'Idempotency-Key': options.idempotency_key || this.generateIdempotencyKey()
}
});
return response.data;
}
/**
* Vidéo IA - Transfert de mouvements
*/
async processVideo(
videoPath: string,
imagePath: string,
options: {
webhook_url?: string;
idempotency_key?: string;
} = {}
): Promise {
const form = new FormData();
form.append('video', fs.createReadStream(videoPath));
form.append('image', fs.createReadStream(imagePath));
if (options.webhook_url) form.append('webhook_url', options.webhook_url);
const response = await this.client.post('/videoai', form, {
headers: {
...form.getHeaders(),
'Idempotency-Key': options.idempotency_key || this.generateIdempotencyKey()
}
});
return response.data;
}
/**
* Text to Video - Génération vidéo depuis texte
*/
async textToVideo(
prompt: string,
options: {
webhook_url?: string;
idempotency_key?: string;
} = {}
): Promise {
const response = await this.client.post('/text2video', {
prompt,
webhook_url: options.webhook_url
}, {
headers: {
'Idempotency-Key': options.idempotency_key || this.generateIdempotencyKey()
}
});
return response.data;
}
/**
* Musique IA - Composition musicale
*/
async generateMusic(
prompt: string,
options: {
webhook_url?: string;
idempotency_key?: string;
} = {}
): Promise {
const response = await this.client.post('/musicai', {
prompt,
webhook_url: options.webhook_url
}, {
headers: {
'Idempotency-Key': options.idempotency_key || this.generateIdempotencyKey()
}
});
return response.data;
}
/**
* Vérifier le statut d'un job
*/
async getJobStatus(jobId: string): Promise {
const response = await this.client.get(`/jobs/${jobId}`);
return response.data;
}
/**
* Annuler un job en cours
*/
async cancelJob(jobId: string): Promise {
await this.client.post(`/jobs/${jobId}/cancel`);
}
/**
* Attendre la complétion d'un job (polling)
*/
async waitForCompletion(
jobId: string,
options: {
pollInterval?: number;
maxWaitTime?: number;
} = {}
): Promise {
const pollInterval = options.pollInterval || 5000;
const maxWaitTime = options.maxWaitTime || 300000; // 5 min
const startTime = Date.now();
while (true) {
const job = await this.getJobStatus(jobId);
if (job.status === 'completed' || job.status === 'failed') {
return job;
}
if (Date.now() - startTime > maxWaitTime) {
throw new Error('Job timeout: max wait time exceeded');
}
await this.sleep(pollInterval);
}
}
/**
* Consulter le solde de crédits
*/
async getCredits(): Promise<{ credits: number }> {
const response = await this.client.get('/credits');
return response.data;
}
/**
* Vérifier la signature d'un webhook
*/
verifyWebhookSignature(
payload: string,
signature: string,
secret: string
): boolean {
const hmac = crypto.createHmac('sha256', secret);
const digest = 'sha256=' + hmac.update(payload).digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(digest)
);
}
}
export default MetaborgClient;
import MetaborgClient from './metaborg-client';
import express from 'express';
const client = new MetaborgClient({
apiKey: process.env.METABORG_API_KEY!,
maxRetries: 3
});
const app = express();
app.use(express.json());
// Endpoint pour déclencher une génération
app.post('/api/generate-video', async (req, res) => {
try {
const { videoPath, imagePath } = req.body;
// Créer le job avec webhook
const job = await client.processVideo(videoPath, imagePath, {
webhook_url: `${process.env.BASE_URL}/webhooks/metaborg`
});
res.json({
job_id: job.job_id,
status: job.status,
message: 'Job créé, vous serez notifié par webhook'
});
} catch (error: any) {
console.error('Error:', error.response?.data || error.message);
res.status(500).json({ error: error.message });
}
});
// Webhook pour recevoir les notifications
app.post('/webhooks/metaborg', async (req, res) => {
const signature = req.headers['x-metaborg-signature'] as string;
const payload = JSON.stringify(req.body);
// Vérifier la signature
if (!client.verifyWebhookSignature(payload, signature, process.env.WEBHOOK_SECRET!)) {
return res.status(401).json({ error: 'Invalid signature' });
}
const { event, data } = req.body;
if (event === 'job.completed') {
console.log('Job completed:', data.job_id);
console.log('Result URL:', data.result.url);
// Télécharger le résultat, notifier l'utilisateur, etc.
// await downloadResult(data.result.url);
// await notifyUser(data.job_id, data.result.url);
} else if (event === 'job.failed') {
console.error('Job failed:', data.job_id, data.error);
// Notifier l'utilisateur de l'échec
}
res.status(200).send('OK');
});
app.listen(3000, () => {
console.log('Server running on port 3000');
});
pip install requests python-dotenv tenacity
import requests
import time
import hmac
import hashlib
import uuid
from typing import Optional, Dict, Any
from tenacity import retry, stop_after_attempt, wait_exponential, retry_if_exception_type
class MetaborgAPIError(Exception):
"""Exception personnalisée pour les erreurs API"""
def __init__(self, status_code: int, error: Dict[str, Any]):
self.status_code = status_code
self.error = error
super().__init__(f"API Error {status_code}: {error.get('message', 'Unknown error')}")
class MetaborgClient:
def __init__(
self,
api_key: str,
base_url: str = "https://api.yourdomain.com/v1",
timeout: int = 30,
max_retries: int = 3
):
self.api_key = api_key
self.base_url = base_url
self.timeout = timeout
self.max_retries = max_retries
self.session = requests.Session()
self.session.headers.update({
'Authorization': f'Bearer {api_key}',
'User-Agent': 'MetaborgClient-Python/1.0'
})
def _generate_idempotency_key(self) -> str:
return str(uuid.uuid4())
@retry(
stop=stop_after_attempt(3),
wait=wait_exponential(multiplier=1, min=1, max=60),
retry=retry_if_exception_type((requests.exceptions.RequestException, MetaborgAPIError))
)
def _make_request(
self,
method: str,
endpoint: str,
**kwargs
) -> Dict[str, Any]:
url = f"{self.base_url}{endpoint}"
try:
response = self.session.request(
method,
url,
timeout=self.timeout,
**kwargs
)
# Handle rate limiting
if response.status_code == 429:
retry_after = int(response.headers.get('Retry-After', 60))
print(f"Rate limited. Waiting {retry_after}s...")
time.sleep(retry_after)
raise MetaborgAPIError(429, {'message': 'Rate limited'})
# Handle client errors
if 400 <= response.status_code < 500:
raise MetaborgAPIError(response.status_code, response.json().get('error', {}))
# Handle server errors (will retry)
if response.status_code >= 500:
raise MetaborgAPIError(response.status_code, {'message': 'Server error'})
response.raise_for_status()
return response.json()
except requests.exceptions.RequestException as e:
print(f"Request error: {e}")
raise
def process_image(
self,
image_path: str,
prompt: Optional[str] = None,
webhook_url: Optional[str] = None,
idempotency_key: Optional[str] = None
) -> Dict[str, Any]:
"""Image IA - Retouche et modification d'images"""
files = {'image': open(image_path, 'rb')}
data = {}
if prompt:
data['prompt'] = prompt
if webhook_url:
data['webhook_url'] = webhook_url
headers = {
'Idempotency-Key': idempotency_key or self._generate_idempotency_key()
}
return self._make_request('POST', '/imageai', files=files, data=data, headers=headers)
def process_video(
self,
video_path: str,
image_path: str,
webhook_url: Optional[str] = None,
idempotency_key: Optional[str] = None
) -> Dict[str, Any]:
"""Vidéo IA - Transfert de mouvements"""
files = {
'video': open(video_path, 'rb'),
'image': open(image_path, 'rb')
}
data = {}
if webhook_url:
data['webhook_url'] = webhook_url
headers = {
'Idempotency-Key': idempotency_key or self._generate_idempotency_key()
}
return self._make_request('POST', '/videoai', files=files, data=data, headers=headers)
def text_to_video(
self,
prompt: str,
webhook_url: Optional[str] = None,
idempotency_key: Optional[str] = None
) -> Dict[str, Any]:
"""Text to Video - Génération vidéo depuis texte"""
json_data = {'prompt': prompt}
if webhook_url:
json_data['webhook_url'] = webhook_url
headers = {
'Idempotency-Key': idempotency_key or self._generate_idempotency_key()
}
return self._make_request('POST', '/text2video', json=json_data, headers=headers)
def generate_music(
self,
prompt: str,
webhook_url: Optional[str] = None,
idempotency_key: Optional[str] = None
) -> Dict[str, Any]:
"""Musique IA - Composition musicale"""
json_data = {'prompt': prompt}
if webhook_url:
json_data['webhook_url'] = webhook_url
headers = {
'Idempotency-Key': idempotency_key or self._generate_idempotency_key()
}
return self._make_request('POST', '/musicai', json=json_data, headers=headers)
def get_job_status(self, job_id: str) -> Dict[str, Any]:
"""Vérifier le statut d'un job"""
return self._make_request('GET', f'/jobs/{job_id}')
def cancel_job(self, job_id: str) -> None:
"""Annuler un job en cours"""
self._make_request('POST', f'/jobs/{job_id}/cancel')
def wait_for_completion(
self,
job_id: str,
poll_interval: int = 5,
max_wait_time: int = 300
) -> Dict[str, Any]:
"""Attendre la complétion d'un job (polling)"""
start_time = time.time()
while True:
job = self.get_job_status(job_id)
if job['status'] in ('completed', 'failed'):
return job
if time.time() - start_time > max_wait_time:
raise TimeoutError(f'Job {job_id} timeout: max wait time exceeded')
time.sleep(poll_interval)
def get_credits(self) -> Dict[str, Any]:
"""Consulter le solde de crédits"""
return self._make_request('GET', '/credits')
@staticmethod
def verify_webhook_signature(
payload: str,
signature: str,
secret: str
) -> bool:
"""Vérifier la signature d'un webhook"""
expected = 'sha256=' + hmac.new(
secret.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)
from flask import Flask, request, jsonify
from metaborg_client import MetaborgClient
import os
app = Flask(__name__)
client = MetaborgClient(api_key=os.getenv('METABORG_API_KEY'))
@app.route('/api/generate-video', methods=['POST'])
def generate_video():
try:
data = request.json
video_path = data['video_path']
image_path = data['image_path']
# Créer le job avec webhook
job = client.process_video(
video_path,
image_path,
webhook_url=f"{os.getenv('BASE_URL')}/webhooks/metaborg"
)
return jsonify({
'job_id': job['job_id'],
'status': job['status'],
'message': 'Job créé, vous serez notifié par webhook'
})
except Exception as e:
return jsonify({'error': str(e)}), 500
@app.route('/webhooks/metaborg', methods=['POST'])
def metaborg_webhook():
signature = request.headers.get('X-Metaborg-Signature')
payload = request.get_data(as_text=True)
# Vérifier la signature
if not client.verify_webhook_signature(
payload,
signature,
os.getenv('WEBHOOK_SECRET')
):
return jsonify({'error': 'Invalid signature'}), 401
data = request.json
event = data['event']
job_data = data['data']
if event == 'job.completed':
print(f"Job completed: {job_data['job_id']}")
print(f"Result URL: {job_data['result']['url']}")
# Traiter le résultat
elif event == 'job.failed':
print(f"Job failed: {job_data['job_id']}, Error: {job_data.get('error')}")
return 'OK', 200
if __name__ == '__main__':
app.run(port=3000)
- Utilisez les webhooks — Plus efficace que le polling, réduit les appels API
- Implémentez l'idempotence — Utilisez Idempotency-Key pour éviter les doublons
- Gérez les retries — Exponential backoff pour les 429 et 5xx
- Sécurisez vos clés — Variables d'environnement, jamais en clair dans le code
- Vérifiez les signatures — Validez tous les webhooks avec HMAC-SHA256
- Timeout appropriés — 30s pour uploads, adaptez selon vos fichiers
- Logs structurés — Loggez job_id, request_id pour le debugging
- Monitoring — Alertes sur taux d'erreurs, latence, crédits bas
- Ne pollez pas trop fréquemment — Minimum 5s entre chaque check
- Ne commitez pas vos clés API — Utilisez .env et .gitignore
- N'ignorez pas les rate limits — Respectez les headers Retry-After
- Ne stockez pas les résultats longtemps — URLs expirent après 7 jours
- N'envoyez pas de fichiers géants — Compressez avant si > 50MB
- Ne faites pas de retry infinis — Max 3-5 tentatives recommandé
Metaborg est entièrement conforme au Règlement Général sur la Protection des Données (RGPD). Nous respectons vos droits et garantissons la protection de vos données personnelles.
- Droit d'accès — Consultez toutes les données que nous détenons sur vous à tout moment
- Droit de rectification — Modifiez vos informations personnelles directement depuis votre compte
- Droit à l'effacement — Supprimez définitivement votre compte et toutes vos données en un clic
- Droit à la portabilité — Exportez vos données dans un format standard (JSON, CSV)
- Droit d'opposition — Refusez le traitement de vos données à des fins marketing
- Fichiers uploadés — Suppression automatique après 24 heures
- Résultats générés — Conservation 7 jours puis suppression définitive
- Données de compte — Conservation tant que le compte est actif
- Logs d'activité — Conservation 90 jours pour des raisons de sécurité
Toutes vos données sont stockées et traitées exclusivement en Union Européenne, sur des serveurs basés en France et en Allemagne. Nous ne transférons jamais vos données hors de l'UE.
- En transit — TLS 1.3 avec Perfect Forward Secrecy pour tous les transferts
- Au repos — Chiffrement AES-256 pour tous les fichiers stockés
- Clés API — Hashage bcrypt avec salt unique par clé
- Mots de passe — Hashage Argon2id, jamais stockés en clair
- Pare-feu WAF — Protection contre les attaques DDoS, injections SQL, XSS
- Rate Limiting — Limitation automatique des requêtes abusives
- Monitoring 24/7 — Surveillance en temps réel des menaces
- Sauvegardes — Backups automatiques quotidiens, rétention 30 jours
- Disaster Recovery — Plan de reprise d'activité testé mensuellement
- Authentification à deux facteurs (2FA) — Disponible via TOTP (Google Authenticator, Authy)
- Sessions sécurisées — Expiration automatique après 30 jours d'inactivité
- Détection d'anomalies — Alertes en cas de connexion suspecte
- Révocation instantanée — Déconnexion de tous les appareils en un clic
- Génération sécurisée — Clés cryptographiquement aléatoires de 256 bits
- Permissions granulaires — Limitez les droits par clé (lecture seule, génération uniquement)
- Rotation facilitée — Créez et révoquez des clés à tout moment
- Audit trail — Logs détaillés de toutes les utilisations de clés API
| Standard | Statut | Description |
|---|---|---|
| RGPD | ✅ Conforme | Règlement européen sur la protection des données |
| ISO 27001 | ✅ Certifié | Gestion de la sécurité de l'information |
| SOC 2 Type II | 🔄 En cours | Audit de sécurité et disponibilité |
| PCI DSS | ✅ Level 1 | Sécurité des paiements par carte |
- Pentests réguliers — Audits de sécurité trimestriels par des experts indépendants
- Bug Bounty Program — Programme de récompenses pour les chercheurs en sécurité
- Scans automatiques — Analyse quotidienne des vulnérabilités (OWASP Top 10)
- Code Review — Revue de sécurité systématique avant chaque déploiement
En cas d'incident de sécurité, notre équipe suit un protocole strict :
- Détection de contenu sensible — Analyse automatique de tous les uploads et générations
- Filtrage CSAM — Protection renforcée contre les contenus d'abus sur mineurs (PhotoDNA)
- Blocage deepfakes malveillants — Prévention des usurpations d'identité et désinformation
- Respect des droits d'auteur — Vérification de la propriété intellectuelle
Les utilisations suivantes sont strictement interdites :
- Génération de contenu illégal, violent, ou haineux
- Création de deepfakes non-consensuels ou trompeurs
- Usurpation d'identité ou atteinte à la réputation
- Violation de droits d'auteur ou de propriété intellectuelle
- Harcèlement, intimidation, ou discrimination
Nous publions trimestriellement un rapport de transparence détaillant :
- Nombre de requêtes gouvernementales reçues et traitées
- Statistiques de modération de contenu (retraits, suspensions)
- Incidents de sécurité survenus et mesures prises
- Évolution de nos certifications et audits
| Limite | Valeur | Note |
|---|---|---|
| Taille maximale | 10 MB | Formats JPG, PNG, WebP |
| Résolution maximale | 4096 x 4096 px | Redimensionnement automatique si supérieur |
| Résolution minimale | 256 x 256 px | Qualité optimale à partir de 512x512 |
| Temps de traitement | 5-30 secondes | Moyenne : 15 secondes |
| Rate limit (web) | Illimité | Limité uniquement par vos crédits |
| Rate limit (API) | 60 req/min | Ajustable sur demande pour Enterprise |
| Limite | Valeur | Note |
|---|---|---|
| Taille maximale | 100 MB | Compression automatique si nécessaire |
| Durée maximale | 60 secondes | Recommandé : 5-15 secondes |
| Résolution maximale | 1920 x 1080 px | Full HD 1080p |
| Formats supportés | MP4, MOV, WebM | Codec H.264 recommandé |
| FPS recommandé | 24-30 fps | Meilleurs résultats à 25 fps |
| Temps de traitement | 30-120 secondes | Varie selon la durée et qualité |
| Rate limit (API) | 30 req/min | Traitement asynchrone |
| Limite | Valeur | Note |
|---|---|---|
| Longueur prompt | 500 caractères | Descriptions détaillées encouragées |
| Durée vidéo | 5 secondes | Fixe pour garantir la qualité |
| Résolution sortie | 720p HD | 1280 x 720 pixels |
| Format sortie | MP4 (H.264) | Compatible tous navigateurs |
| Temps de traitement | 60-180 secondes | Génération IA complexe |
| Rate limit (API) | 20 req/min | File d'attente prioritaire disponible |
| Limite | Valeur | Note |
|---|---|---|
| Longueur prompt | 300 caractères | Style, instruments, ambiance |
| Durée audio | 30 secondes | Exportable en boucle |
| Format sortie | MP3 320kbps | Qualité studio |
| Fréquence échantillonnage | 44.1 kHz | Standard CD audio |
| Temps de traitement | 20-45 secondes | Composition en temps réel |
| Rate limit (API) | 60 req/min | Même limite qu'Image IA |
- Pas de limite de requêtes — Utilisez la plateforme autant que vous voulez
- Limité uniquement par vos crédits — Achetez des crédits selon vos besoins
- File d'attente intelligente — Traitement prioritaire en période de forte affluence
- Uploads simultanés — Jusqu'à 5 fichiers en parallèle
| Endpoint | Rate Limit | Burst | Fenêtre |
|---|---|---|---|
| Image IA / Musique IA | 60 req/min | 10 req/sec | Glissante 60s |
| Vidéo IA | 30 req/min | 5 req/sec | Glissante 60s |
| Text to Video | 20 req/min | 3 req/sec | Glissante 60s |
| Status / Credits | 300 req/min | 50 req/sec | Glissante 60s |
- Rate limits personnalisés — Adaptés à votre volume d'utilisation
- SLA garanti — 99.95% de disponibilité contractuelle
- Support prioritaire — Temps de réponse < 4h, 24/7
- File d'attente dédiée — Traitement en priorité absolue
- Webhooks personnalisés — Notifications en temps réel
| Opération | P50 | P95 | P99 |
|---|---|---|---|
| Upload fichier | 200ms | 800ms | 2s |
| Génération Image IA | 12s | 25s | 35s |
| Génération Vidéo IA | 45s | 90s | 140s |
| Génération Text to Video | 90s | 150s | 200s |
| Génération Musique IA | 25s | 40s | 50s |
| API Status Check | 50ms | 150ms | 300ms |
P50 = 50% des requêtes, P95 = 95% des requêtes, P99 = 99% des requêtes
- Compression des uploads — Réduisez la taille de vos fichiers avant upload (ImageOptim, FFmpeg)
- Résolution adaptée — N'envoyez pas de 4K si vous n'avez besoin que de HD
- Batch processing — Groupez vos requêtes API pour réduire l'overhead
- Webhooks vs Polling — Utilisez les webhooks au lieu de poll le statut en boucle
- CDN pour résultats — Les URLs de résultats sont servies via CDN pour un téléchargement ultra-rapide
| Plan | SLA | Uptime Mensuel | Downtime Max |
|---|---|---|---|
| Starter / Standard | 99.5% | ~99.5% | ~3.6 heures/mois |
| Premium | 99.9% | ~99.9% | ~43 minutes/mois |
| Max / Enterprise | 99.95% | ~99.95% | ~21 minutes/mois |
- Maintenance planifiée — Mardis 3h-5h CET (heure creuse)
- Notification préalable — Email 48h avant toute intervention
- Déploiements progressifs — Rolling updates sans downtime
- Status page en temps réel — status.metaborg.app pour suivre les incidents
Accédez à des métriques détaillées depuis votre compte :
- Utilisation par outil — Nombre de générations et crédits consommés
- Historique complet — Tous vos jobs avec timestamps et statuts
- Performance tracking — Temps de traitement moyen de vos requêtes
- Alertes personnalisées — Notifications quand crédits < seuil défini
- Export CSV — Téléchargez vos données d'utilisation pour analyse
- Dashboard dédié — Visualisation en temps réel de vos appels API
- Quotas & Rate Limits — Suivi de votre consommation vs limites
- Error tracking — Taux d'erreurs 4xx/5xx avec détails
- Latency percentiles — P50, P95, P99 de vos requêtes
- Webhooks logs — Historique complet des callbacks envoyés
Pour les volumes importants (> 10,000 requêtes/jour), contactez notre équipe Enterprise :
- Infrastructure dédiée — Instances réservées pour votre organisation
- Rate limits personnalisés — Adaptés à votre charge de travail
- Régions personnalisées — Déploiement dans votre région géographique
- SLA renforcé — 99.99% de disponibilité avec crédits en cas de non-respect
- Support dédié — Customer Success Manager attitré
- Onboarding personnalisé — Formation de vos équipes techniques
| Pack | Crédits | Prix |
|---|---|---|
| Starter | 9 ⭐ | 9€ |
| Standard | 29 ⭐ | 29€ |
| Premium | 108 ⭐ | 49€ |
| Max | 216 ⭐ | 99€ |
| Fonctionnalité | Coût | Temps |
|---|---|---|
| Image IA | 1 ⭐ | ~15s |
| Vidéo IA | 3 ⭐ | ~60s |
| Création de Vidéo (4s) | 3 ⭐ | ~60s |
| Création de Vidéo (8s) | 6 ⭐ | ~60s |
| Musique IA | 1 ⭐ | ~30s |
- Avec le pack Starter (9 crédits) : 9 Image IA, ou 3 Vidéo IA, ou 3 Création Vidéo 4s, ou 9 Musique IA
- Avec le pack Standard (29 crédits) : 29 Image IA, ou 9 Vidéo IA, ou 9 Création Vidéo 4s, ou 29 Musique IA
- Avec le pack Premium (108 crédits) : 108 Image IA, ou 36 Vidéo IA, ou 36 Création Vidéo 4s, ou 18 Création Vidéo 8s
- Avec le pack Max (216 crédits) : 216 Image IA, ou 72 Vidéo IA, ou 72 Création Vidéo 4s, ou 36 Création Vidéo 8s
Nous garantissons le remboursement automatique de vos crédits dans les cas suivants :
- Échec technique — Si la génération échoue pour une raison technique de notre côté (erreur serveur, timeout, crash), vos crédits sont recrédités automatiquement dans les 5 minutes
- Fichier corrompu — Si le résultat généré est corrompu ou non-téléchargeable, contactez le support avec l'ID de tâche pour un remboursement immédiat
- Non-conformité technique — Si le résultat ne respecte pas les spécifications techniques promises (résolution, format, durée), remboursement sur demande
Pas de remboursement dans ces cas :
- Qualité subjective — Le résultat ne correspond pas à vos attentes artistiques ou créatives (ex: "le visage ne ressemble pas assez", "la musique n'est pas à mon goût")
- Fichiers sources inadaptés — Mauvaise qualité des fichiers uploadés (images floues, vidéos trop sombres, résolution insuffisante)
- Utilisation incorrecte — Non-respect des limites techniques documentées (fichiers trop volumineux, formats non supportés)
- Prompt imprécis — Pour Text to Video et Musique IA, un prompt vague ou contradictoire ne justifie pas un remboursement
Réponse sous 24h ouvrées
Support prioritaire 24/7
Si vous rencontrez un bug ou un problème technique, incluez les informations suivantes dans votre message :
- Votre nom d'utilisateur ou email
- L'outil utilisé (Image IA, Vidéo IA, Text to Video, Musique IA)
- Une description détaillée du problème
- Des captures d'écran si possible
- L'ID de la tâche si disponible
- Consultez cette documentation pour les guides d'utilisation détaillés
- Vérifiez la section FAQ pour les questions courantes
- Contactez notre support technique pour une assistance personnalisée
- Explorez notre API Reference pour les intégrations avancées