# API SciFig et serveur MCP

Créez des figures scientifiques, des graphiques et des diagrammes de flux depuis du code ou des assistants IA. Version lisible : https://scifig.ai/fr/developers. OpenAPI : https://scifig.ai/api/v1/openapi.json.

## Vue d’ensemble

L’API SciFig crée des figures scientifiques, des graphiques et des diagrammes de flux avec les mêmes moteurs, tarifs et crédits que le site. L’URL de base est `https://scifig.ai/api/v1`. Chaque création est une tâche : vous la créez, puis consultez son état et ses fichiers de sortie.

Les assistants IA peuvent utiliser SciFig via le serveur MCP distant à l’adresse `https://mcp.scifig.ai/mcp` (voir « Serveur MCP » ci-dessous).

## Authentification

Envoyez `Authorization: Bearer <credential>` avec chaque requête, sauf pour `/pricing`, `/openapi.json` et `/openapi.yaml`.

- Une clé avec un droit d’écriture nécessite un abonnement actif ou un solde de crédits achetés positif et expire après 30, 90 ou 365 jours. Une clé en lecture seule peut être sans expiration.
- Jetons d’accès OAuth (`sf_at_…`) : délivrés aux clients MCP après votre autorisation, ils sont valables une heure. Les clients qui demandent `offline_access` reçoivent également un jeton de renouvellement (`sf_rt_…`) valable 30 jours. Révoquez une application dans Paramètres → Clés API → Applications connectées.
- Huit autorisations indépendantes sont sélectionnables. Aucune n’en implique une autre : téléversement, lecture des tâches et lecture du solde exigent chacun leur autorisation. `images:generate`, `images:edit`, `images:convert`, `charts:generate`, `flowcharts:generate`, `files:write`, `jobs:read`, `credits:read`
- `GET /api/v1/capabilities` exige des identifiants valides, sans autorisation métier. Seul `granted_scopes` est renvoyé, sans solde, offre ni données du compte.
- Tous les appels authentifiés, y compris les refus de permission et autres erreurs, sont conservés 30 jours sous forme de métadonnées. Aucun prompt, contenu, nom de fichier, adresse IP ou identifiant secret. Des enregistrements peuvent manquer en cas de panne. Clés, historique et applications connectées affichent chacun 10 lignes par page. Les crédits décrivent le règlement de la tâche associée ; ne pas additionner les lignes de répétition comme des dépenses.
- Seuls les clients `CIMD` autorisés peuvent utiliser `private_key_jwt` avec signature à clé publique vérifiée et protection contre le rejeu. L’enregistrement dynamique anonyme reste limité à `none` ou `client_secret_basic`.

## Démarrage rapide

```bash
curl https://scifig.ai/api/v1/images/generations \
  -H "Authorization: Bearer $SCIFIG_API_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Prefer: wait=25" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "Mitochondrial electron transport chain, labelled", "aspect_ratio": "4:3"}'
```

La réponse contient la tâche. Si elle n’est pas terminée, le statut est `202` avec `Location: /api/v1/jobs/{id}`. Interrogez cette URL toutes les quelques secondes jusqu’à ce que `status` soit `succeeded`, `failed` ou `canceled`, puis téléchargez les fichiers via `outputs[].download_url`.

## Conventions

- Les requêtes et les réponses utilisent JSON ; les fichiers et les données des graphiques sont envoyés en `multipart/form-data`. Les noms des champs sont en `snake_case`.
- Chaque `POST` qui crée un résultat exige un en-tête `Idempotency-Key` (1–255 caractères ASCII visibles). Réessayer avec la même clé et le même corps renvoie la même tâche, sans double facturation ; la même clé avec un corps différent renvoie `409 IDEMPOTENCY_CONFLICT`. Deux requêtes simultanées avec la même clé renvoient la même tâche, ou `409 IDEMPOTENCY_IN_PROGRESS` pour celle qui arrive pendant l’admission de l’autre. Une requête refusée (par exemple `INSUFFICIENT_CREDITS`) conserve cette réponse pour sa clé : après un achat de crédits ou un changement d’abonnement, envoyez-la avec une nouvelle clé. Une fois la tâche créée, une erreur récupérable (`429`, `503`, `409 IDEMPOTENCY_IN_PROGRESS`) ou `500 INTERNAL_ERROR` inclut `details.job_id` : réessayez avec la même clé ou interrogez `GET /jobs/{job_id}`, sans utiliser de nouvelle clé. Une tâche acceptée mais impossible à relire reçoit une réponse `202` avec le statut `queued`.
- `Prefer: wait=N` (1–30 secondes) retient la réponse jusqu’à la fin de la tâche ou l’expiration du délai.
- Chaque réponse inclut `X-Request-Id`. Les erreurs utilisent `{"error": {"code", "message", "request_id", "details"}}`.
- L’API n’est pas accessible depuis un navigateur via CORS ; appelez-la depuis un serveur ou un script.

## Points de terminaison et crédits

| Point de terminaison | Usage | Crédits |
| --- | --- | --- |
| POST /images/generations | Générer une illustration scientifique | 50 / 75 / 100 (standard / advanced / premium) |
| POST /images/edits | Modifier une image : par instruction, avec un masque pour redessiner une zone, fond blanc, rapport largeur/hauteur, changement de couleurs ou remplacement de texte | 50 / 75 / 100 ; avec un masque ou `replace_text` 100 |
| POST /images/text-detections | Détecter le texte d’une image avant de le remplacer | 0 |
| POST /images/upscales | Agrandir en 2K, 4K ou 8K | 50 / 100 / 150 |
| POST /images/conversions | Convertir en SVG, PNG, PDF, TIFF ou PPTX ; convertir les SVG de diagrammes de flux en PNG, PDF, TIFF ou PPTX | SVG 150 ; autres formats gratuits, 200 par jour |
| POST /charts/generations | Tracer un graphique à partir de données CSV, TSV ou Excel | 100 |
| POST /charts/edits | Modifier la version la plus récente d’un graphique | 100 |
| POST /flowcharts/generations | Dessiner un diagramme de flux en SVG | 100 |
| POST /flowcharts/edits | Modifier la version la plus récente d’un diagramme de flux | 100 |
| POST /files | Importer une image, un masque ou une pièce jointe de diagramme de flux | 0 |
| GET /jobs/{id} | Statut, crédits et liens de téléchargement d’une tâche | 0 |
| GET /jobs | Vos tâches récentes, les plus récentes d’abord, avec pagination par curseur | 0 |
| GET /files/{file_id} | Télécharger un fichier | 0 |
| GET /credits | Solde, offre et limites des tâches | 0 |
| GET /pricing | Prix en crédits de chaque opération, sans authentification | 0 |
| GET /openapi.json | Description OpenAPI 3.1, sans authentification | 0 |
| GET /openapi.yaml | La même description en YAML | 0 |

## Champs des requêtes

`POST /images/generations` : `prompt` (obligatoire), `aspect_ratio` (`1:1`, `2:3`, `3:2`, `3:4`, `4:3`, `4:5`, `5:4`, `9:16`, `16:9`, `21:9`), `quality` (`standard`, `advanced`, `premium`), `style`, `palette` (identifiant de préréglage ou 1–4 couleurs `#RRGGBB`), `reference_file_ids` (jusqu’à 3). Certains modèles et images de référence exigent une offre payante ; l’erreur le précise.

`POST /images/edits` : `image` (une `file_id`) et `operation`. `instruct` (par défaut) accepte `instruction` (jusqu’à 2000 caractères) et, en option, `mask` (PNG ; le blanc marque la zone à modifier ; un masque utilise toujours le modèle `premium`). `white_background` remplace le fond par du blanc uni. `aspect_ratio` adapte l’image à `aspect_ratio`. `recolor` applique `palette` (1–8 couleurs `#RRGGBB`) ou choisit une palette. Toutes ces opérations acceptent `quality`. `replace_text` accepte `text_detection` (l’identifiant renvoyé par `POST /images/text-detections` pour la même image) et `replacements` (`[{"index", "text"}]`), et utilise toujours le modèle `premium` de retouche de texte.

`POST /images/text-detections` : `image`. Renvoie `id`, les dimensions `width` et `height` de l’image et `texts` (`index`, `text`, `corners`) dans l’ordre de lecture. Gratuit ; partage la limite du site de 20 détections toutes les 15 minutes.

`POST /images/upscales` : `image`, `scale` (`2k` ; `4k` nécessite au moins Starter, `8k` au moins Plus ; un solde de pack de crédits supérieur à zéro est assimilé à Pro).

`POST /images/conversions` : `image`, `format` (`svg`, `png`, `pdf`, `tiff`, `pptx`). Pour SVG, `vector_mode` vaut `editable_text` (par défaut) ou `full_vector` ; la source est une image PNG, JPEG ou WebP. Pour les autres formats, `dpi` vaut 300, 600 ou 1000. La résolution DPI est inscrite dans les métadonnées et définit la taille de la page ; les pixels ne sont pas rééchantillonnés (agrandissez d’abord l’image pour obtenir davantage de pixels). La source est une image PNG ou JPEG, ou le SVG d’un diagramme de flux. WebP n’est pas accepté ; PNG et TIFF exigent une source PNG. Le SVG d’un diagramme de flux est rendu sur le serveur avec Arial et Noto. `width` (256–4096, valeur par défaut 2048) définit le côté le plus long en pixels ; le texte que ces polices ne peuvent pas afficher est refusé. Le PPTX contient l’image rendue, pas des formes modifiables.

`POST /charts/generations` (`multipart`) : `data` (CSV, TSV, TXT, XLSX ou XLS, jusqu’à 8 MB ; le séparateur des fichiers texte est détecté), `request` (graphique souhaité, 1–16 000 caractères), et les champs facultatifs `chart_types` (séparés par des virgules), `journal_style` (`default`, `nature`, `science`, `cell`, `plos`, `acs`), `figure_width` (`single`, `onehalf`, `double`), `color_palette`, `sheet_name` (feuille d’un classeur qui en contient plusieurs). Les données illisibles renvoient `400 INVALID_REQUEST`, avec `details.field = data` et le code de l’analyseur dans `details.reason`. Sorties : PNG, PDF, TIFF et EPS.

`POST /charts/edits` et `POST /flowcharts/edits` : `job` (tâche précédente de graphique ou de diagramme de flux) et `instruction` (1–16 000 caractères pour les graphiques, 1–8 000 pour les diagrammes de flux). La retouche repart du résultat de cette tâche en conservant les données, les types de graphiques et le style de revue (graphiques), ou le rapport d’aspect (diagrammes de flux). Comme dans l’espace de travail, seule la dernière version peut être modifiée. Si une version plus récente existe (y compris créée sur le site), la réponse est `409 REVISION_CONFLICT` avec `details.reason = NOT_LATEST_REVISION`. Tant que la tâche parente est en cours, la réponse est une erreur récupérable `409 REVISION_CONFLICT` (`PARENT_JOB_RUNNING`, avec `Retry-After`) ; si elle a échoué, la réponse est `400 INVALID_REQUEST` (`JOB_NOT_SUCCEEDED`).

`POST /flowcharts/generations` : `prompt` (1–8 000 caractères), `aspect_ratio` (`auto` ou l’un des rapports ci-dessus), et, en option, `attachment_file_ids` (jusqu’à 8, téléversés avec l’usage `flowchart_attachment`). Sortie : SVG.

## Tâches

`status` vaut `queued`, `processing`, `succeeded`, `failed` ou `canceled`. `credits` contient `reserved`, `charged` et `refunded`, lus dans le registre comptable. Une tâche échouée est remboursée.

Une génération ou une retouche dont le délai est dépassé a le statut `failed`, avec `error.code = TASK_TIMED_OUT` et un horodatage `late_delivery_until`. Jusqu’à cette date, le résultat peut encore être livré gratuitement ; continuez à consulter la tâche au lieu d’en créer une autre.

Un refus lié à la politique de contenu se traduit par `422 CONTENT_REJECTED` lors de la création de la requête, ou par une tâche `failed` avec `error.code = CONTENT_REJECTED` s’il intervient pendant l’exécution. Dans les deux cas, les crédits sont remboursés.

Chaque sortie possède une `file_id`, un `format` et une `download_url` valable une heure sans authentification. Les sorties PNG incluent aussi `width` et `height`. Les graphiques et les diagrammes de flux comportent une `editor_url` qui ouvre le résultat dans son espace de travail sur le site ; les illustrations et les conversions n’en ont pas.

Les images de sortie (PNG, JPEG, WebP) peuvent être transmises par `file_id` comme `image` ou référence aux points de terminaison d’image. Les conversions acceptent des sources jusqu’à 20 MB. Pour PNG, PDF, TIFF et PPTX, elles acceptent les images PNG ou JPEG et le SVG d’un diagramme de flux, mais pas WebP.

## Fichiers

`POST /files` (`multipart`) : `file` et `purpose` (`image`, `mask` ou `flowchart_attachment`). Images : PNG, JPEG ou WebP jusqu’à 20 MB ; masques : PNG jusqu’à 8 MB ; pièces jointes de diagramme de flux : formats de l’espace de travail FlowChart jusqu’à 32 MB. La réponse est `201` avec `file_id`, `purpose`, `content_type`, `size_bytes`, `expires_at` et `created_at`. Les fichiers téléversés restent utilisables 24 heures. Ils partagent les limites de téléversement du site ; au-delà, la réponse est `429 RATE_LIMITED`. Un `Idempotency-Key` facultatif (1–255 caractères ASCII visibles) permet de répéter le téléversement : le même compte, la même clé et le même `purpose` renvoient le premier fichier avec `201`, sans le téléverser à nouveau ni consommer la limite. La même clé et le même `purpose` avec d’autres octets renvoient `409 IDEMPOTENCY_CONFLICT`. Répéter un téléversement expiré renvoie `400 INVALID_REQUEST` avec `details.reason = FILE_EXPIRED` ; téléversez à nouveau avec une nouvelle clé.

`GET /files/{file_id}` télécharge votre fichier avec vos identifiants, ou via la `download_url` signée d’une tâche. Un lien signé expiré ou modifié renvoie `404`, tout comme tous les liens d’un compte banni ou en cours de suppression.

## Erreurs

| Code | HTTP | Signification |
| --- | --- | --- |
| UNAUTHORIZED | 401 | Identifiants manquants ou invalides. |
| ACCOUNT_UNAVAILABLE | 401 | Ce compte ne peut pas utiliser l’API. |
| SCOPE_DENIED | 403 | Les identifiants ne donnent pas cette autorisation. |
| INVALID_REQUEST | 400 | La requête est invalide. |
| IDEMPOTENCY_KEY_REQUIRED | 400 | Un en-tête Idempotency-Key contenant 1 à 255 caractères ASCII visibles est obligatoire. |
| IDEMPOTENCY_CONFLICT | 409 | Cet Idempotency-Key a déjà été utilisé pour une autre requête. |
| IDEMPOTENCY_IN_PROGRESS | 409 | Une requête avec cet Idempotency-Key est toujours en cours de traitement. |
| NOT_FOUND | 404 | Introuvable. |
| REVISION_CONFLICT | 409 | La tâche de graphique ou de diagramme de flux ne peut pas être modifiée actuellement : `NOT_LATEST_REVISION`, `EDIT_IN_PROGRESS`, ou `PARENT_JOB_RUNNING` tant que la tâche parente est en cours. |
| PAYLOAD_TOO_LARGE | 413 | Le corps de la requête est trop volumineux. |
| INSUFFICIENT_CREDITS | 402 | Crédits insuffisants. |
| CONTENT_REJECTED | 422 | La politique de contenu a refusé la requête. Le refus est renvoyé avec `422` lors de la création de la requête, ou dans `error.code` d’une tâche échouée s’il survient pendant son exécution ; les crédits sont remboursés dans les deux cas. |
| PLAN_REQUIRED | 403 | Votre offre n’inclut pas cette option. |
| RATE_LIMITED | 429 | Trop de requêtes, de tâches par heure, de conversions par jour ou d’importations ; `details.reason` précise la cause. |
| CONCURRENCY_LIMITED | 429 | Trop de tâches sont en cours pour ce compte. |
| SERVICE_UNAVAILABLE | 503 | Le service est temporairement indisponible. Réessayez avec le même Idempotency-Key. |
| TASK_FAILED | 502 | La tâche a échoué et ses crédits ont été remboursés. Envoyez une nouvelle requête avec un nouvel Idempotency-Key pour réessayer. |
| INTERNAL_ERROR | 500 | Erreur interne. |

`details.reason` indique la cause exacte de `INVALID_REQUEST`, `PLAN_REQUIRED` et d’erreurs similaires. Seul `INSUFFICIENT_CREDITS` inclut `details.top_up_url` ; son `utm_source` vaut `api` ou `mcp` selon le canal de la requête.

Codes présents uniquement dans une tâche échouée :

| error.code | Signification | Que faire |
| --- | --- | --- |
| TASK_TIMED_OUT | La tâche a dépassé le délai et les crédits ont été remboursés. Une génération ou une modification d’illustration peut contenir `late_delivery_until` : le résultat peut encore arriver gratuitement jusqu’à cette échéance. | Continuez à consulter la tâche jusqu’à `late_delivery_until` ; sinon, envoyez une nouvelle requête avec une nouvelle clé |
| CONTENT_REJECTED | La politique de contenu a refusé le résultat pendant l’exécution ; les crédits ont été remboursés. Le même code est renvoyé avec `422` lorsque la requête elle-même est refusée à la création. | Modifiez la description ou l’entrée et utilisez une nouvelle clé |
| ADMISSION_INCOMPLETE | La tâche n’a jamais démarré, car une erreur permettant une nouvelle tentative l’a empêchée. Aucun crédit n’a été utilisé. | Envoyez la même requête avec le même Idempotency-Key |
| TASK_NOT_FOUND | La tâche a été admise, mais son exécution est désormais introuvable. | Envoyez une nouvelle requête avec une nouvelle clé |
| TASK_FAILED | La tâche a échoué et les crédits ont été remboursés. Tout échec de moteur sans code public propre devient `TASK_FAILED` ; le code du moteur se trouve dans `details.reason`. | Envoyez une nouvelle requête avec une nouvelle clé |
| INTERNAL_ERROR | La tâche a échoué sans indiquer de raison ; les crédits ont été remboursés. | Envoyez une nouvelle requête avec une nouvelle clé |

## Limites de débit

- Création : 20 requêtes par minute et par identifiant d’accès, et 40 par minute et par compte. Un identifiant OAuth est comptabilisé par client et par compte.
- Lecture : 120 requêtes par minute et par identifiant d’accès.
- Les tâches simultanées dépendent de votre offre ; au plus 200 tâches démarrent par heure. Ces deux limites sont partagées avec le site.
- Les réponses ayant passé l’authentification et la vérification de portée incluent `X-RateLimit-Limit`, `X-RateLimit-Remaining` et `X-RateLimit-Reset` ; une réponse `429` inclut `Retry-After`.
- `429 RATE_LIMITED` peut avoir plusieurs causes. Consultez `details.reason` et la [page des limites de débit](/fr/docs/api/rate-limits).

## Installer le plugin officiel SciFig

Ajoutez la marketplace SciFig dans Claude Code pour installer la connexion MCP distante et quatre skills dédiés à la configuration, aux figures, aux graphiques et à l’export.

```text
/plugin marketplace add lilingm963/scifig-plugins
/plugin install scifig@scifig-plugins
```

- [Présentation de l’API et du MCP](/fr/developers)
- [Guide d’installation MCP](/fr/developers/mcp/install.md)
- [Référence de l’API](/fr/docs/api)
- [Découvrir le plugin officiel](https://github.com/lilingm963/scifig-plugins)
- [Fiche du MCP Registry](https://registry.modelcontextprotocol.io/v0.1/servers/io.github.lilingm963%2Fscifig/versions/1.0.0)

## Serveur MCP

URL du serveur : `https://mcp.scifig.ai/mcp`, Streamable HTTP. Les clients prenant en charge OAuth se connectent en ouvrant une session SciFig et en autorisant l’accès ; ceux qui envoient des en-têtes peuvent utiliser une clé API sous la forme `Authorization: Bearer sk_live_…`.

| Outil | Fonction |
| --- | --- |
| generate_figure | Créer une illustration scientifique à partir d’une description |
| edit_figure | Modifier une image : instruction, éventuellement dans une zone masquée, fond blanc, rapport largeur/hauteur, changement de couleurs ou remplacement de texte |
| detect_text | Détecter le texte d’une image avant de le remplacer |
| upscale_figure | Agrandir en 2K, 4K ou 8K |
| convert_figure | Convertir en SVG, PNG, PDF, TIFF ou PPTX |
| generate_chart | Tracer un graphique à partir de texte CSV ou TSV ou de lignes JSON, jusqu’à 1 MB |
| edit_chart | Modifier la version la plus récente d’un graphique |
| generate_flowchart | Dessiner un diagramme de flux en SVG, éventuellement à partir de 8 pièces jointes au maximum |
| edit_flowchart | Modifier la version la plus récente d’un diagramme de flux |
| get_job | Statut, crédits et liens de téléchargement d’une tâche |
| list_figures | Tâches récentes |
| get_credit_balance | Solde de crédits, offre et limites |

Les outils de création attendent jusqu’à 25 secondes. Si une tâche est encore en cours, appelez `get_job` plus tard ; rappeler l’outil de création crée et facture une nouvelle tâche. Les résultats répertorient chaque lien de téléchargement et, pour les graphiques et diagrammes de flux, le lien d’ouverture dans l’éditeur SciFig.

L’initialisation utilise `/capabilities` sans `credits:read`. Chaque outil exige son autorisation. Le téléversement depuis une URL externe ou data URL exige aussi `files:write`, vérifié avant téléchargement ; réutiliser un `file_id` ne l’exige pas. Les téléchargements intégrés et `get_job` exigent `jobs:read`. Sinon, conservez le résultat et expliquez la limite sans élargir les accès sans accord.

## Connectez votre client

Claude, sur claude.ai et dans Claude Desktop : Paramètres → Connecteurs → Ajouter un connecteur personnalisé. Saisissez l’URL du serveur, connectez-vous à SciFig et autorisez l’accès.

Ouvrez `Plugins` dans ChatGPT et ajoutez une connexion MCP personnalisée privée. Les menus dépendent du compte.

Claude Code :

```bash
claude mcp add --transport http scifig https://mcp.scifig.ai/mcp
```

Codex (`~/.codex/config.toml`):

```toml
[mcp_servers.scifig]
url = "https://mcp.scifig.ai/mcp"
```

Ouvrez Cursor `Customize` → MCP et modifiez `mcp.json` en conservant les serveurs existants. Sélectionnez ensuite `Authenticate` et autorisez SciFig dans le navigateur.

```json
{
  "mcpServers": {
    "scifig": {
      "url": "https://mcp.scifig.ai/mcp"
    }
  }
}
```

Les clients sans OAuth peuvent ajouter l’en-tête `Authorization: Bearer sk_live_…` avec une clé API créée dans Paramètres → Clés API.
