API et MCP
Envoyez une image PNG ou JPEG depuis un script, un plugin ou un agent IA et récupérez un SVG. L'API utilise le calcul sur le serveur de Homotope : même moteur, même file, mêmes crédits et même plafond d'image que l'atelier.
Description complète (OpenAPI 3.1) : /api/v1/openapi.json.
Démarrage en 3 étapes
-
Créez une clé dans l'atelier, « Mon compte » → «
Clés d'API ». Elle commence par
hmt_live_et n'est affichée qu'une fois : gardez-la dans un gestionnaire de secrets, jamais dans un dépôt ni dans une URL. -
Envoyez une image :
POST /api/v1/jobsrépond aussitôt202avec l'identifiant du calcul, sans attendre la fin. -
Sondez puis téléchargez : interrogez
GET /api/v1/jobs/{id}toutes les 2 à 5 secondes jusqu'à l'étatdone, puis récupérezGET /api/v1/jobs/{id}/svg, ouGET /api/v1/jobs/{id}/result?format=pdf(svg,pdf,dxfoueps).
Exemples avec curl
La clé passe dans l'en-tête Authorization: Bearer …, et seulement là.
export HOMOTOPE_KEY="hmt_live_…"
# Vérifier la clé
curl -sS https://homotope.example/api/v1/me \
-H "Authorization: Bearer $HOMOTOPE_KEY"
# Envoyer une image (options facultatives : préréglage, nom, réglages)
curl -sS https://homotope.example/api/v1/jobs \
-H "Authorization: Bearer $HOMOTOPE_KEY" \
-F [email protected] \
-F 'options={"preset":"logo","name":"Logo","options":{"export":{"precision":2}}}'
# → 202 {"id":"…","state":"queued","links":{…}}
# Palette imposée : tracer avec VOS couleurs (2 à 64, distinctes), aucune autre n'est inventée
curl -sS https://homotope.example/api/v1/jobs \
-H "Authorization: Bearer $HOMOTOPE_KEY" \
-F [email protected] \
-F 'options={"preset":"logo","palette":["#E30613","#0057B8","#FFFFFF"]}'
# Sonder jusqu'à "state": "done"
curl -sS https://homotope.example/api/v1/jobs/ID \
-H "Authorization: Bearer $HOMOTOPE_KEY"
# Télécharger le SVG
curl -sS -o logo.svg https://homotope.example/api/v1/jobs/ID/svg \
-H "Authorization: Bearer $HOMOTOPE_KEY"
# Le même résultat en PDF, EPS ou DXF (découpe ; tolerance : courbes aplaties, en px)
curl -sS -OJ "https://homotope.example/api/v1/jobs/ID/result?format=dxf&tolerance=0.05" \
-H "Authorization: Bearer $HOMOTOPE_KEY"
# Séparations : une couche par couleur (SVG à calques, DXF à couches ; ZIP pour PDF et EPS)
curl -sS -OJ "https://homotope.example/api/v1/jobs/ID/result?format=svg&layers=1" \
-H "Authorization: Bearer $HOMOTOPE_KEY"
# … ou un fichier par couleur, en ZIP
curl -sS -OJ "https://homotope.example/api/v1/jobs/ID/result?format=pdf&layers=zip" \
-H "Authorization: Bearer $HOMOTOPE_KEY"
# Prêt pour la découpe ? Contrôle du DXF (outil de 0,3 mm, frontières communes fusionnées)
curl -sS "https://homotope.example/api/v1/jobs/ID/cutcheck?tool_mm=0.3&merge_shared=true" \
-H "Authorization: Bearer $HOMOTOPE_KEY"
# → {"id":"…","report":{"blocking":0,"check":2,"totals":{…},"issues":[…],…}}
# Derniers calculs (20 par défaut, 100 au plus ; "nextCursor" pour la suite)
curl -sS "https://homotope.example/api/v1/jobs?limit=50" \
-H "Authorization: Bearer $HOMOTOPE_KEY"
# Annuler un calcul en file, ou supprimer un résultat
curl -sS -X DELETE https://homotope.example/api/v1/jobs/ID \
-H "Authorization: Bearer $HOMOTOPE_KEY"
Préréglages : logo, illustration, pixel-art,
line-art, centerline (trait unique : chemins
stroke d'une seule passe, pour laser, traceur ou broderie), photo.
Les réglages admis et leurs bornes sont ceux du panneau « Avancé » de l'atelier, décrits
dans le document OpenAPI (JobOptions).
Formats du résultat
- Tous les formats sont produits à la volée depuis le SVG du calcul : même géométrie, mêmes couleurs, même ordre. 1 px = 1 pt (1/72 de pouce).
- PDF 1.4 et EPS 3.0 : vectoriels, page à la taille de l'image. L'EPS n'a pas de transparence.
-
DXF R12 (découpe laser, traceur, Cricut) : contours fermés, trous
compris, une couche par couleur nommée en hexadécimal (
FF8800), en millimètres. Le DXF n'a pas de remplissage : c'est le contour qui compte pour la découpe ; préférez le mode « Découpé » (aucun chevauchement). Le rectangle de fond n'y figure pas (il ferait un cadre) :include_background=truepour le garder.merge_shared=truefusionne les frontières communes : un bord partagé par deux formes voisines n'est écrit, donc découpé, qu'une fois. -
Séparations (
layers) :layers=1donne une couche par couleur (SVG à calques Inkscape et Illustrator, DXF à couches, ZIP d'un fichier par couleur pour le PDF et l'EPS) ;layers=zipdonne toujours un ZIP d'un fichier par couleur, nommés<nom>-<hexadécimal>.<ext>. Chaque fichier est la zone VISIBLE de sa couleur (fichiers disjoints) : il faut un calcul en mode « Découpé », sinon422(stacked_separations). Le SVG à calques suit l'ordre de peinture (un calque par série de formes de même couleur). -
Palette imposée (
palettedansoptions) : 2 à 64 couleurs hexadécimales distinctes ; chaque pixel prend la plus proche (OKLab). Tramage et seuil de couverture :options.quantize.fixedPalette(document OpenAPI). Aucune table de couleurs n'est fournie : envoyez les vôtres. -
Conversion bornée à 4 Mo de SVG ; au-delà, téléchargez le SVG. 60 conversions (PDF, DXF,
EPS) par heure et par clé, 120 par compte ;
503(busy) si une conversion du compte est déjà en cours.
Prêt pour la découpe ?
GET /api/v1/jobs/{id}/cutcheck analyse le DXF que produirait
…/result?format=dxf (mêmes tolerance,
include_background, merge_shared), en lecture seule, et rend un
rapport JSON :
-
Bloquant (
blocking) : contour ouvert, deux contours qui se croisent (crossing), contour qui se recoupe (self-intersection), contours superposés. -
À vérifier (
check) : détail plus fin que l’outil (thin,tool_mm, 0,2 mm par défaut), petit îlot (island, sousisland_mm2, 1 mm² par défaut), contour de plus de 1 000 nœuds (nodes). -
Chaque problème porte une position (
box, en px de l'image, Y vers le bas), une mesure (value, en mm, mm², nœuds ou points) et un message en français. Les traits du centre-ligne (préréglagecenterline) sont ouverts par nature : jamais signalés. -
Information (
info, hors deblockingetcheck) : frontière commune de deux formes voisines coupée deux fois (overlap), réglée parmerge_shared=true. -
Mêmes limites et mêmes places que les conversions (il occupe le même thread). Une analyse
très lourde s'arrête proprement :
200avectruncated: true(totaux minimaux), ou422(too_complex).
Droits
- Pas d'essai gratuit par l'API ni par le MCP : les calculs d'essai du mois sont réservés à l'atelier.
- Chaque calcul consomme d'abord le quota Pro du mois, puis un crédit (voir les tarifs). Un calcul qui échoue, ou annulé avant de démarrer, est rendu.
-
Sans quota Pro restant ni crédit, l'envoi est refusé en
402(payment_required) avant toute lecture de l'image. Un compte gratuit peut créer une clé : ses envois reçoivent402tant qu'il n'a ni Pro ni crédit. - Mêmes formats (PNG, JPEG, 80 Mo au plus) et même plafond de pixels que l'atelier.
Limites
- 60 requêtes par minute par clé (toutes les routes), et 120 requêtes par minute par compte, toutes clés confondues.
-
30 calculs par heure par clé : au-delà,
429avec l'en-têteRetry-After(secondes). Un envoi refusé ne compte pas. -
1 calcul en cours et 3 en file par clé : au-delà,
429(too_many_jobs) avecRetry-After: 10; attendez qu'un calcul se termine. -
30 refus
401par adresse IP sur 15 minutes (clé absente ou invalide) : au-delà,429. Vérifiez votre clé avant de réessayer. - 10 clés actives au plus par compte ; une clé révoquée l'est définitivement.
Erreurs
Toute erreur a la forme {"error": {"code": "…", "message": "…"}}, message en
français.
| Statut | Codes | Que faire |
|---|---|---|
| 401 | invalid_api_key |
Clé absente, inconnue ou révoquée. |
| 402 | payment_required |
Ni quota Pro restant ni crédit : achetez un pack ou passez Pro. |
| 404 | not_found |
Calcul inconnu (ou d'un autre compte). |
| 408 | upload_timeout |
Envoi trop long ou trop lent : le délai vaut max(60 s, taille annoncée ÷ 256 Ko/s), et le débit doit rester d'au moins 32 Ko/s. Vérifiez la connexion, puis réessayez. |
| 409 | not_ready |
SVG demandé trop tôt : sondez jusqu'à done. |
| 410 | gone |
Résultat supprimé (rétention ou suppression). |
| 413 |
payload_too_large, too_large,
quota_exceeded
|
Fichier trop lourd, image trop grande, ou stockage plein. |
| 415 | unsupported_media_type |
Ni PNG ni JPEG (signature du fichier, jamais son nom ni son type déclaré). |
| 422 |
stacked_separations, too_complex,
unconvertible
|
Un fichier par couleur demandé sur un résultat empilé (choisissez le mode « découpé ») ; conversion ou contrôle de découpe trop long ou trop lourd (simplifiez le tracé) ; résultat non convertible. Réessayer tel quel ne sert à rien. |
| 429 |
rate_limited, too_many_jobs,
too_many_uploads
|
Attendez le délai de Retry-After, sans boucler. |
| 503 | busy, storage_unavailable, unavailable |
Places de conversion prises (busy, avec Retry-After), ou
service momentanément indisponible : réessayez plus tard.
|
Serveur MCP (agents IA)
Homotope expose un serveur MCP (Model Context Protocol), simple façade de cette API, en transport « Streamable HTTP » :
-
URL :
https://homotope.example/mcp - En-tête :
Authorization: Bearer hmt_live_…(votre clé d'API) - Mêmes droits, mêmes limites et mêmes crédits que l'API.
Exemple de configuration d'un client MCP (la clé reste chez vous) :
{
"mcpServers": {
"homotope": {
"type": "http",
"url": "https://homotope.example/mcp",
"headers": { "Authorization": "Bearer hmt_live_…" }
}
}
}
Outils proposés à l'agent :
-
vectorize_image: une image enimage_base64(environ 6 Mo au plus) ou uneimage_urlhttps publique, plusfilename,preset,palette(couleurs imposées, hexadécimal) etoptionsfacultatifs ; rend aussitôt{ job_id, state }, sans attendre la fin du calcul. get_job: l'état d'un calcul (job_id).-
get_svg: le SVG d'un calcul terminé (image/svg+xml), ou une erreur claire s'il n'est pas prêt. -
get_result: le résultat ensvg,pdf,dxfoueps(format, ettolerancepour le DXF) ;layers: séparations (true, ou"zip"pour un fichier par couleur) ; le PDF et le ZIP arrivent encodés en base64. -
check_cut: « prêt pour la découpe ? » — le rapport du contrôle du DXF (tool_mm,island_mm2,merge_shared…), commeGET /api/v1/jobs/{id}/cutcheck. list_vectorizations: les derniers calculs (limit).
Une erreur d'outil porte le statut et le code de l'API (402, 413, 429…) et un message en
français. Une image_url doit être publique : https, port 443, ni adresse privée
ni locale, 3 redirections au plus, lue en 15 secondes.
Pas d'OAuth : la clé d'API suffit. Pas de transport stdio : le serveur est
distant. Le serveur ne garde aucune session entre deux requêtes.