import Foundationlet url = URL(string: "https://api.apimart.ai/v1/images/generations")!let payload: [String: Any] = [ "model": "seedream-5-0-flash", "prompt": "Paysage urbain nocturne de style cyberpunk, néons se reflétant sur les rues mouillées", "size": "16:9", "resolution": "2K"]var request = URLRequest(url: url)request.httpMethod = "POST"request.setValue("Bearer <token>", forHTTPHeaderField: "Authorization")request.setValue("application/json", forHTTPHeaderField: "Content-Type")request.httpBody = try? JSONSerialization.data(withJSONObject: payload)let task = URLSession.shared.dataTask(with: request) { data, response, error in if let error = error { print("Error: \(error)") return } if let data = data, let responseString = String(data: data, encoding: .utf8) { print(responseString) }}task.resume()
using System;using System.Net.Http;using System.Text;using System.Threading.Tasks;class Program{ static async Task Main(string[] args) { var url = "https://api.apimart.ai/v1/images/generations"; var payload = @"{ ""model"": ""seedream-5-0-flash"", ""prompt"": ""Paysage urbain nocturne de style cyberpunk, néons se reflétant sur les rues mouillées"", ""size"": ""16:9"", ""resolution"": ""2K"" }"; using var client = new HttpClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer <token>"); var content = new StringContent(payload, Encoding.UTF8, "application/json"); var response = await client.PostAsync(url, content); var result = await response.Content.ReadAsStringAsync(); Console.WriteLine(result); }}
(* Requires cohttp and yojson libraries *)open Lwtopen Cohttpopen Cohttp_lwt_unixlet url = "https://api.apimart.ai/v1/images/generations"let payload = {|{ "model": "seedream-5-0-flash", "prompt": "Paysage urbain nocturne de style cyberpunk, néons se reflétant sur les rues mouillées", "size": "16:9", "resolution": "2K"}|}let () = let headers = Header.init () |> fun h -> Header.add h "Authorization" "Bearer <token>" |> fun h -> Header.add h "Content-Type" "application/json" in let body = Cohttp_lwt.Body.of_string payload in let response = Client.post ~headers ~body (Uri.of_string url) >>= fun (resp, body) -> body |> Cohttp_lwt.Body.to_string >|= fun body_str -> print_endline body_str in Lwt_main.run response
import 'dart:convert';import 'package:http/http.dart' as http;void main() async { final url = Uri.parse('https://api.apimart.ai/v1/images/generations'); final payload = { 'model': 'seedream-5-0-flash', 'prompt': 'Paysage urbain nocturne de style cyberpunk, néons se reflétant sur les rues mouillées', 'size': '16:9', 'resolution': '2K' }; final response = await http.post( url, headers: { 'Authorization': 'Bearer <token>', 'Content-Type': 'application/json', }, body: jsonEncode(payload), ); print(response.body);}
library(httr)library(jsonlite)url <- "https://api.apimart.ai/v1/images/generations"payload <- list( model = "seedream-5-0-flash", prompt = "Paysage urbain nocturne de style cyberpunk, néons se reflétant sur les rues mouillées", size = "16:9", resolution = "2K")response <- POST( url, add_headers( Authorization = "Bearer <token>", `Content-Type` = "application/json" ), body = toJSON(payload, auto_unbox = TRUE), encode = "raw")cat(content(response, "text"))
import Foundationlet url = URL(string: "https://api.apimart.ai/v1/images/generations")!let payload: [String: Any] = [ "model": "seedream-5-0-flash", "prompt": "Paysage urbain nocturne de style cyberpunk, néons se reflétant sur les rues mouillées", "size": "16:9", "resolution": "2K"]var request = URLRequest(url: url)request.httpMethod = "POST"request.setValue("Bearer <token>", forHTTPHeaderField: "Authorization")request.setValue("application/json", forHTTPHeaderField: "Content-Type")request.httpBody = try? JSONSerialization.data(withJSONObject: payload)let task = URLSession.shared.dataTask(with: request) { data, response, error in if let error = error { print("Error: \(error)") return } if let data = data, let responseString = String(data: data, encoding: .utf8) { print(responseString) }}task.resume()
using System;using System.Net.Http;using System.Text;using System.Threading.Tasks;class Program{ static async Task Main(string[] args) { var url = "https://api.apimart.ai/v1/images/generations"; var payload = @"{ ""model"": ""seedream-5-0-flash"", ""prompt"": ""Paysage urbain nocturne de style cyberpunk, néons se reflétant sur les rues mouillées"", ""size"": ""16:9"", ""resolution"": ""2K"" }"; using var client = new HttpClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer <token>"); var content = new StringContent(payload, Encoding.UTF8, "application/json"); var response = await client.PostAsync(url, content); var result = await response.Content.ReadAsStringAsync(); Console.WriteLine(result); }}
(* Requires cohttp and yojson libraries *)open Lwtopen Cohttpopen Cohttp_lwt_unixlet url = "https://api.apimart.ai/v1/images/generations"let payload = {|{ "model": "seedream-5-0-flash", "prompt": "Paysage urbain nocturne de style cyberpunk, néons se reflétant sur les rues mouillées", "size": "16:9", "resolution": "2K"}|}let () = let headers = Header.init () |> fun h -> Header.add h "Authorization" "Bearer <token>" |> fun h -> Header.add h "Content-Type" "application/json" in let body = Cohttp_lwt.Body.of_string payload in let response = Client.post ~headers ~body (Uri.of_string url) >>= fun (resp, body) -> body |> Cohttp_lwt.Body.to_string >|= fun body_str -> print_endline body_str in Lwt_main.run response
import 'dart:convert';import 'package:http/http.dart' as http;void main() async { final url = Uri.parse('https://api.apimart.ai/v1/images/generations'); final payload = { 'model': 'seedream-5-0-flash', 'prompt': 'Paysage urbain nocturne de style cyberpunk, néons se reflétant sur les rues mouillées', 'size': '16:9', 'resolution': '2K' }; final response = await http.post( url, headers: { 'Authorization': 'Bearer <token>', 'Content-Type': 'application/json', }, body: jsonEncode(payload), ); print(response.body);}
library(httr)library(jsonlite)url <- "https://api.apimart.ai/v1/images/generations"payload <- list( model = "seedream-5-0-flash", prompt = "Paysage urbain nocturne de style cyberpunk, néons se reflétant sur les rues mouillées", size = "16:9", resolution = "2K")response <- POST( url, add_headers( Authorization = "Bearer <token>", `Content-Type` = "application/json" ), body = toJSON(payload, auto_unbox = TRUE), encode = "raw")cat(content(response, "text"))
import Foundationlet url = URL(string: "https://api.apimart.ai/v1/images/generations")!let payload: [String: Any] = [ "model": "seedream-5-0-flash", "prompt": "Paysage urbain nocturne de style cyberpunk, néons se reflétant sur les rues mouillées", "size": "16:9", "resolution": "2K"]var request = URLRequest(url: url)request.httpMethod = "POST"request.setValue("Bearer <token>", forHTTPHeaderField: "Authorization")request.setValue("application/json", forHTTPHeaderField: "Content-Type")request.httpBody = try? JSONSerialization.data(withJSONObject: payload)let task = URLSession.shared.dataTask(with: request) { data, response, error in if let error = error { print("Error: \(error)") return } if let data = data, let responseString = String(data: data, encoding: .utf8) { print(responseString) }}task.resume()
using System;using System.Net.Http;using System.Text;using System.Threading.Tasks;class Program{ static async Task Main(string[] args) { var url = "https://api.apimart.ai/v1/images/generations"; var payload = @"{ ""model"": ""seedream-5-0-flash"", ""prompt"": ""Paysage urbain nocturne de style cyberpunk, néons se reflétant sur les rues mouillées"", ""size"": ""16:9"", ""resolution"": ""2K"" }"; using var client = new HttpClient(); client.DefaultRequestHeaders.Add("Authorization", "Bearer <token>"); var content = new StringContent(payload, Encoding.UTF8, "application/json"); var response = await client.PostAsync(url, content); var result = await response.Content.ReadAsStringAsync(); Console.WriteLine(result); }}
(* Requires cohttp and yojson libraries *)open Lwtopen Cohttpopen Cohttp_lwt_unixlet url = "https://api.apimart.ai/v1/images/generations"let payload = {|{ "model": "seedream-5-0-flash", "prompt": "Paysage urbain nocturne de style cyberpunk, néons se reflétant sur les rues mouillées", "size": "16:9", "resolution": "2K"}|}let () = let headers = Header.init () |> fun h -> Header.add h "Authorization" "Bearer <token>" |> fun h -> Header.add h "Content-Type" "application/json" in let body = Cohttp_lwt.Body.of_string payload in let response = Client.post ~headers ~body (Uri.of_string url) >>= fun (resp, body) -> body |> Cohttp_lwt.Body.to_string >|= fun body_str -> print_endline body_str in Lwt_main.run response
import 'dart:convert';import 'package:http/http.dart' as http;void main() async { final url = Uri.parse('https://api.apimart.ai/v1/images/generations'); final payload = { 'model': 'seedream-5-0-flash', 'prompt': 'Paysage urbain nocturne de style cyberpunk, néons se reflétant sur les rues mouillées', 'size': '16:9', 'resolution': '2K' }; final response = await http.post( url, headers: { 'Authorization': 'Bearer <token>', 'Content-Type': 'application/json', }, body: jsonEncode(payload), ); print(response.body);}
library(httr)library(jsonlite)url <- "https://api.apimart.ai/v1/images/generations"payload <- list( model = "seedream-5-0-flash", prompt = "Paysage urbain nocturne de style cyberpunk, néons se reflétant sur les rues mouillées", size = "16:9", resolution = "2K")response <- POST( url, add_headers( Authorization = "Bearer <token>", `Content-Type` = "application/json" ), body = toJSON(payload, auto_unbox = TRUE), encode = "raw")cat(content(response, "text"))
Tous les points de terminaison de l’API nécessitent une authentification Bearer TokenObtenez votre clé API :Visitez la page de gestion des clés API pour obtenir votre clé APIAjoutez-la à l’en-tête de la requête :
Authorization: Bearer YOUR_API_KEY
Modèle à image unique : seedream-5-0-flash ne génère qu’une image par requête (sauf lors de la décomposition en calques). Les paramètres suivants sont refusés (HTTP 400, aucune tâche, aucun frais) :
n > 1
sequential_image_generation (la génération groupée n’est pas prise en charge)
stream (le streaming n’est pas pris en charge)
tools (la recherche web n’est pas prise en charge)
plus de 10 éléments dans image_urls
Édition interactive
Utilisez des coordonnées <point> / <bbox> dans le prompt, ou chargez une image annotée à la main, afin de cibler précisément les modifications.
Coordonnées d’un point : <point>x y</point> (indiquent un point unique ; le modèle détermine la zone affectée)
Coordonnées d’un cadre : <bbox>x1 y1 x2 y2</bbox> (indiquent les coordonnées du coin supérieur gauche et du coin inférieur droit afin de contrôler précisément la taille de la zone d’édition)
Décomposition en calques
Décomposez une image en une image de base et jusqu’à 16 calques PNG transparents, avec leurs informations de position et d’empilement.
Description textuelle pour la génération d’imagesFacultatif lorsque layer_decomposition: true ; s’il est omis, le modèle identifie et sépare automatiquement les principaux éléments de l’image.Outre le chinois et l’anglais, la génération native de texte prend en charge le russe, l’arabe, le filipino, le thaï, le turc, le coréen, le malais, l’espagnol, le portugais, l’indonésien, le français, l’allemand, le vietnamien et le japonais.
Conseil : restez sous 600 mots anglais ; une description trop longue peut entraîner une perte de détails.
Le palier peut être indiqué directement dans size ou via le champ d’extension API Mart resolution :
{ "size": "2K" }
{ "resolution": "2K" }
Ces deux syntaxes sont équivalentes. Si seul un palier est indiqué, décrivez la mise en page souhaitée dans le prompt (par exemple, “affiche en portrait” ou “couverture en paysage”) et laissez le modèle choisir le format d’image.
transparent n’est disponible que pour les requêtes image-vers-image comportant exactement une image d’entrée qui possède déjà un canal alpha ; output_format: "png" est également requis.
Indique s’il faut décomposer l’image en calques. Lorsque cette option est activée, le modèle renvoie une image de base et jusqu’à 16 calques PNG avec canal alpha.Une seule image PNG ou JPEG est requise. Elle doit contenir entre [262144, 36000000] pixels au total et ne pas dépasser 30 Mo. size n’accepte que 1K, 1.5K, 2K ou auto, avec auto par défaut. output_format ne contrôle que le format de l’image de base ; les calques décomposés sont toujours au format PNG.
{ "model": "seedream-5-0-flash", "prompt": "Remplacer la tenue de l'image 1 par la tenue de l'image 2", "image_urls": [ "https://example.com/person.jpg", "https://example.com/dress.jpg" ], "resolution": "2K", "size": "auto"}
{ "model": "seedream-5-0-flash", "prompt": "Un mignon chat orange sur un rebord de fenêtre au soleil de l'après-midi, cinématique", "resolution": "1.5K", "size": "16:9"}
Vous pouvez aussi utiliser des coordonnées <bbox> normalisées sur 0–1000 afin d’identifier précisément les éléments à extraire :
{ "model": "seedream-5-0-flash", "prompt": "Sépare l'image en calques précis. Le texte se trouve dans <bbox>180 64 812 198</bbox> ; le perroquet dans <bbox>347 305 642 997</bbox>.", "image_urls": ["https://example.com/poster.png"], "layer_decomposition": true}
Décrivez en langage naturel les annotations dessinées à la main dans l’image :
{ "model": "seedream-5-0-flash", "prompt": "Modifie l'image en suivant le croquis. Ajoute une pile de magazines dans la zone marquée en bas à gauche et une tasse de café dans la zone marquée à droite. Supprime tous les traits du croquis et conserve la composition.", "image_urls": ["https://example.com/sketch.png"], "size": "2K", "output_format": "png"}
Ou ciblez précisément les emplacements avec <point> / <bbox> :
{ "model": "seedream-5-0-flash", "prompt": "Place le sujet de l'image 1 situé dans <bbox>179 283 796 986</bbox> dans l'image 2 à l'emplacement <bbox>118 331 933 871</bbox>.", "image_urls": [ "https://example.com/a.png", "https://example.com/b.png" ]}
Exemple complet : envoyer une tâche et récupérer l’image
Le script suivant illustre le flux complet : envoyer une tâche asynchrone, interroger son état, gérer les échecs et lire l’URL finale de l’image. Remplacez YOUR_API_KEY avant de l’exécuter.
Python
import timeimport requestsAPI_KEY = "YOUR_API_KEY"BASE_URL = "https://api.apimart.ai"headers = { "Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json",}# 1. Envoyer la tâche de générationcreate_response = requests.post( f"{BASE_URL}/v1/images/generations", headers=headers, json={ "model": "seedream-5-0-flash", "prompt": "Une ville d'eau du Jiangnan au style lavis, dans une légère brume matinale", "resolution": "1.5K", "size": "16:9", "output_format": "png", }, timeout=30,)create_response.raise_for_status()task_id = create_response.json()["data"][0]["task_id"]print(f"Tâche envoyée : {task_id}")# 2. Interroger l'état de la tâchewhile True: task_response = requests.get( f"{BASE_URL}/v1/tasks/{task_id}", headers=headers, timeout=30, ) task_response.raise_for_status() task = task_response.json() status = task["status"] print(f"État : {status} ; progression : {task.get('progress', 0)} %") if status == "success": image = task["result"]["images"][0] print("URL de l'image :", image["url"][0]) print("Dimensions de l'image :", image["sizes"][0]) print("Format de l'image :", image["output_formats"][0]) break if status in {"failed", "cancelled"}: raise RuntimeError(task.get("error", f"Tâche {status}")) time.sleep(5)
En cas de réussite, l’endpoint de consultation de la tâche renvoie :
Les images renvoyées sont répliquées dans un stockage géré par la plateforme. Téléchargez-les et conservez-les néanmoins rapidement dans votre propre système ; ne considérez pas l’URL du résultat comme un stockage permanent.
Réponse de décomposition en calques et reconstruction
Les tableaux url, sizes, output_formats et layers se correspondent par indice ; l’indice 0 représente toujours l’image de base :
{ "result": { "images": [{ "url": [ "https://cdn.example.com/images/image_task_xxx_0.jpeg", "https://cdn.example.com/images/image_task_xxx_1.png", "https://cdn.example.com/images/image_task_xxx_2.png" ], "sizes": ["2048x2048", "1273x265", "492x98"], "output_formats": ["jpeg", "png", "png"], "layer_decomposition": true, "layers": [ { "z_index": 0, "size": "2048x2048", "output_format": "jpeg" }, { "z_index": 1, "size": "1273x265", "output_format": "png", "name": "Texte du titre", "description": "Grand texte de titre jaune en police à empattements", "bounding_box": { "absolute": [383, 120, 1655, 384], "normalized": [187, 59, 808, 188] } }, { "z_index": 2, "size": "492x98", "output_format": "png", "name": "Slogan en haut à gauche", "description": "Slogan anglais blanc sur deux lignes", "bounding_box": { "absolute": [140, 451, 631, 548], "normalized": [68, 220, 308, 268] } } ] }] }}
Superposez les calques dans l’ordre croissant de z_index. Pour les reconstruire sur l’image de base de sortie avec des coordonnées absolues :
x = lefty = topw = right - lefth = bottom - top
Pour les reconstruire sur n’importe quel canevas W × H, utilisez les coordonnées normalisées :
x = left / 1000 × Wy = top / 1000 × Hw = (right - left) / 1000 × Wh = (bottom - top) / 1000 × H
La décomposition en calques est facturée par image. Jusqu’à 17 images sont préautorisées lors de l’envoi de la tâche. Une fois la tâche terminée, chaque sortie est classée selon son nombre réel de pixels et facturée séparément ; tout excédent de préautorisation est remboursé automatiquement. Votre solde doit couvrir la préautorisation de 17 images et size: "auto" est préautorisé au palier 2K.
Préautorisation et facturation de la décomposition en calques
Le nombre et les dimensions finales des calques étant inconnus à l’envoi de la tâche, la préautorisation applique des règles prudentes fondées sur la requête :
Pixels exacts : palier déterminé par la surface demandée en pixels.
1K / 1.5K : préautorisation au palier 1K.
2K : préautorisation au palier 2K.
auto : pouvant produire jusqu’à 2K, il est préautorisé au palier 2K.
Après exécution, l’image de base et chaque calque réel sont classés et additionnés individuellement selon leur surface réelle en pixels. L’excédent de préautorisation est remboursé automatiquement. Les calques sont généralement bien plus petits que l’image de base ; une tâche préautorisée au palier 2K peut donc être entièrement facturée au palier 1K.
Exemple : une entrée 1080×1080 est décomposée en 10 images. La tâche est préautorisée pour 17 images × palier 2K. Si les 10 images finales ne dépassent pas 2,61 millions de pixels, la facturation porte sur 10 images × palier 1K et le crédit restant est remboursé automatiquement.
Ni 1K / 1.5K / 2K / auto, ni un format d’image pris en charge, ni des dimensions en pixels valides → 400
Total pixels exacts hors plage
Doit être dans [921600, 4624220]
Rapport pixels exacts hors plage
Doit être dans [1/16, 16]
n > 1 / paramètres d’images groupées
Refusé par le modèle à image unique
Plus de 10 images de référence
Rejected
Décomposition sans image ou avec plusieurs images
Une seule image est requise
Décomposition avec un format ou des pixels exacts
size ne prend en charge que 1K / 1.5K / 2K / auto
Arrière-plan transparent pour texte-vers-image ou entrées multiples
Une seule image d’entrée avec canal alpha est requise
Arrière-plan transparent avec JPEG
Définissez output_format: "png"
stream / tools
Non pris en charge par ce modèle ; renvoie 400
Mode d’optimisation du prompt non valide
Seul standard est pris en charge
⏱️ Génération plus lente : environ 90 s en 1K et 160 s en 2K (priorité à la qualité). Interrogez l’état de la tâche toutes les 5 à 10 secondes et réglez le délai du client sur 5 minutes. Enregistrez rapidement les résultats générés.