Référence de l’API

Récupérez les variables de variable Jar depuis n’importe où — apps iOS/Android, pipelines CI — via REST. En lecture seule, avec le même token que le serveur MCP.

Bêta : l’API et le MCP peuvent changer avant le lancement ; les formats sont désormais versionnés (voir Sortie de code de plateforme), et les changements incompatibles sont annoncés avec 12 mois de cohabitation.

Émettre un token

  1. variablejar.com/app → menu ⋯ d’une carte de projet → Propriétés → la section Tokens d’API (MCP)
  2. Saisissez un nom de token et appuyez sur Créer — le token (vjt_…) n’est affiché qu’une seule fois, juste après l’émission. Conservez-le en lieu sûr.
  3. Un token ne donne accès qu’à ce seul projet. En cas de fuite, révoquez-le immédiatement sur le même écran.

Les tokens expirent (180 jours par défaut, 365 au maximum). Vous recevez une notification dans la cloche 14 jours avant. Seul le propriétaire de l’espace de travail peut émettre un token qui inclut les valeurs texte (STRING) — toutes les langues, traductions non publiées comprises. Vous pouvez aussi limiter un token à certaines collections.

Un token n’est sûr que là où vous le gardez : quiconque le détient reçoit toutes les valeurs de sa portée. Les données exportées via l’API ou le MCP quittent le service et sont traitées sous votre responsabilité.

Endpoint

GET https://variablejar.com/api/v1/variables
Authorization: Bearer vjt_...
curl -H "Authorization: Bearer vjt_..." \
  "https://variablejar.com/api/v1/variables"

Les valeurs texte (STRING) ne sont incluses que si le token a été émis avec les valeurs texte et que vous ajoutez ?include=strings.

Réponse

Les valeurs sont finales, avec les alias ({Collection/key}) résolus. Seules les cellules qui n’ont pas pu être résolues apparaissent dans unresolved avec une raison (broken · cycle · inline), en gardant leur valeur d’origine.

{
  "apiVersion": "v1",
  "project": { "name": "My Variables" },
  "collections": [
    { "name": "Color", "modes": ["light", "dark"] },
    { "name": "Text", "modes": ["en", "ko"] }
  ],
  "tokens": [
    {
      "key": "color/primary",
      "collection": "Color",
      "type": "COLOR",
      "valuesByMode": { "light": "#3B82F6", "dark": "#60A5FA" }
    },
    { "key": "hello", "collection": "Text", "type": "STRING", "valuesByMode": {}, "omitted": "strings" }
  ]
}

Sans include=strings, les tokens STRING sont toujours listés, mais avec un valuesByMode vide et "omitted": "strings".

Sortie de code de plateforme

Ajoutez ?format= pour recevoir du code de plateforme généré au lieu du JSON :

formatSortieContent-Type
css@1 (alias css)Propriétés personnalisées CSS — mode par défaut dans :root, autres modes dans [data-theme="<mode>"]text/css
swift@1 (alias swift)SwiftUI — un type par collection, une instance statique par modetext/plain
compose@1 (alias compose)Jetpack Compose (Kotlin) — même structure que Swifttext/plain

Les formats sont versionnés. Le nom sans version (css) est un alias permanent de @1 — il ne passe jamais de lui-même à une version plus récente. Au sein d’une version, seuls deux types de changement sont admis : corriger une sortie dont la syntaxe n’était pas valide, et corriger l’échappement pour la sécurité ; les deux incrémentent le rev du format (listé par /formats, ci-dessous) et invalident les caches. Tout ce qui change la représentation d’une valeur ou un identifiant constitue une nouvelle version (css@2), et la version précédente reste disponible pendant 12 mois (annoncé par les en-têtes Deprecation et Sunset).

curl -H "Authorization: Bearer vjt_..." \
  "https://variablejar.com/api/v1/variables?format=css" \
  > variables.css

La sortie est déterministe — des tokens identiques produisent toujours des octets identiques, donc la mise en cache ETag/If-None-Match fonctionne comme pour la réponse JSON. Les alias sont toujours résolus en valeurs finales ; les références non résolues sont émises en commentaires, jamais sous forme de valeurs inventées. Un format inconnu renvoie 400 { "error": "unknown_format" }.

Les identifiants sont dérivés des noms de collection et de variable et ne dépendent pas de l’ordre de vos données : réordonner des collections, des variables ou des modes dans Figma ne renomme jamais un token. Quand deux noms aboutissent au même identifiant, celui qui vient en premier dans l’ordre de tri (selon son nom d’origine) garde l’identifiant simple et les autres reçoivent _2, _3 … ; ajouter un nouveau nom en collision peut renuméroter les suffixes existants, évitez donc les noms qui ne diffèrent que par les séparateurs ou la casse. Une même variable reçoit le même identifiant quel que soit le filtre utilisé (collection, include=strings ou un token limité à certaines collections) : les noms sont d’abord fixés sur l’ensemble du projet, puis la réponse est filtrée.

?collection=<name> limite la sortie à une collection (400 unknown_collection si le nom n’existe pas dans le projet). ?view=ai@1 renvoie une vue compacte et assainie pour les agents IA (noms et valeurs uniquement, valeurs texte omises par défaut) ; elle ne se combine pas avec format, et toute autre valeur de view que index (ci-dessous) renvoie 400 unknown_view.

?view=index associé à format renvoie, au lieu du code, l’identifiant que reçoit chaque variable dans ce format — pour vérifier les noms sans analyser le code généré. Les identifiants sont orthographiés comme dans la sortie (les mots-clés Swift/Kotlin gardent leurs accents graves). Les variables texte (STRING) sont exclues de l’index, sauf si le token a été émis avec les valeurs texte et que vous passez include=strings. view=index sans format renvoie 400 unknown_view.

curl -H "Authorization: Bearer vjt_..." \
  "https://variablejar.com/api/v1/variables?format=css@1&view=index"
{
  "format": "css@1",
  "rev": "1-1",
  "identifiers": [
    { "collection": "Color", "key": "btn/bg", "identifier": "--color-btn-bg" }
  ]
}

GET /api/v1/formats liste les formats et versions proposés par ce serveur, avec pour chacun son rev actuel, son nom de fichier et son Content-Type. Il utilise le même token, ne compte ni dans l’utilisation ni dans la limite de requêtes, et prend en charge ETag/If-None-Match comme l’endpoint des variables (pas de X-VJ-Stamp — la liste est statique). Une version remplacée porte en plus "deprecated": { "since": "YYYY-MM-DD", "sunset": "YYYY-MM-DD" } ; sunset n’apparaît que lorsqu’une date est fixée.

{
  "contract": "1",
  "formats": [
    { "id": "css", "version": 1, "spec": "css@1", "rev": "1-1", "alias": "css", "filename": "variables.css", "mime": "text/css; charset=utf-8" },
    { "id": "swift", "version": 1, "spec": "swift@1", "rev": "1-1", "alias": "swift", "filename": "Tokens.swift", "mime": "text/plain; charset=utf-8" },
    { "id": "compose", "version": 1, "spec": "compose@1", "rev": "1-1", "alias": "compose", "filename": "Tokens.kt", "mime": "text/plain; charset=utf-8" }
  ],
  "views": [{ "view": "ai@1", "rev": "1" }]
}

Interrogation périodique et ETag

Les réponses incluent un en-tête ETag. Renvoyez-le en If-None-Match et vous obtiendrez 304 (sans corps) si rien n’a changé — de quoi économiser de la bande passante pour les vérifications périodiques depuis les apps mobiles et la CI. Utilisez la valeur ETag reçue telle quelle (elle peut contenir W/).

curl -i -H "Authorization: Bearer vjt_..." \
  -H 'If-None-Match: "…"' \
  "https://variablejar.com/api/v1/variables"
# HTTP/2 304

Chaque réponse 200 ou 304 porte ces en-têtes :

En-têteSignification
ETag / If-None-MatchRenvoyez le dernier ETag ; si rien n’a changé, vous obtenez 304 sans corps
X-VJ-StampTampon de fraîcheur du contenu du projet + de la portée de ce token (même valeur pour tous les formats d’un même token) — même tampon, mêmes données pour tous les formats
X-VJ-TTLSecondes à attendre avant de revérifier (30–600)
X-VJ-Token-ExpiresDate d’expiration de ce token
X-VJ-ContractVersion du contrat d’API (1)
X-VJ-FormatFormat et version d’une réponse ?format=, par ex. css@1

Erreurs

Les réponses d’erreur ont pour corps { "error": "<code>" }.

StatutSignification
400 unknown_format · unknown_view · unknown_collectionValeur de format ou de view inconnue, ou nom de collection absent du projet
401 unauthorizedToken absent / mal formé / révoqué
401 token_expiredLe token a expiré — émettez-en un nouveau
403 token_inactiveLa personne qui a émis le token a quitté l’espace de travail ou perdu le rôle nécessaire au token
403 plan_requiredL’offre de l’espace de travail n’inclut pas l’accès à l’API
403 scope_deniedinclude=strings exige un token émis avec les valeurs texte
404 not_foundMauvais chemin, ou le projet a été supprimé ou mis à la corbeille
405 method_not_allowedMéthode autre que GET ou OPTIONS (OPTIONS répond à la requête préliminaire CORS par 204)
413 too_largeLe projet dépasse la limite de taille de l’API (25 000 variables ou 24 Mo de données de variables) — déplacez certaines collections vers un autre projet ou contactez support@variablejar.com
426 client_outdatedLe client déclaré (X-VJ-Client) est plus ancien que la version minimale acceptée par ce serveur — mettez à jour @variablejar/mcp
429 rate_limitedTrop de requêtes — réessayez après le nombre de secondes indiqué dans Retry-After
500 internalErreur serveur — si elle persiste après une nouvelle tentative, contactez support@variablejar.com
502 upstream_unreachableLa passerelle de l’API n’a pas pu joindre le backend — réessayez
503 not_configuredLe service n’est pas configuré — contactez support@variablejar.com

Serveur MCP (IDE / agents IA)

Depuis les IDE et les agents de codage IA, le serveur MCP @variablejar/mcp est plus pratique que REST — le même token fonctionne pour les deux. Vous pouvez confier cette page à un agent IA et lui demander de configurer l’intégration pour vous.

Ajoutez à votre configuration MCP (en fixant la version) :

{
  "mcpServers": {
    "variablejar": {
      "command": "npx",
      "args": ["-y", "@variablejar/mcp@0.3.1"],
      "env": { "VARIABLEJAR_TOKEN": "vjt_your_token_here" }
    }
  }
}

L’emplacement du fichier dépend du client :

ClientFichier de configuration
Claude Code.mcp.json à la racine du projet
Cursor.cursor/mcp.json
Autres clients MCPVoir les paramètres de serveurs MCP du client

Outils disponibles :

OutilEntréeDescription
list_collections—Les collections avec leurs modes, le nombre de tokens, la répartition par type et les groupes de premier niveau — commencez ici
list_tokenscollection? prefix? type? query? format? limit (50, max. 200) cursor? include_strings?Tokens paginés, valeurs résolues par mode. La première ligne du bloc de données est toujours total=<n> returned=<m> nextCursor=<c|none>. Avec format (p. ex. css@1), chaque token porte aussi son identifiant dans ce format
get_tokenkey collection? format?Un seul token par clé (p. ex. color/primary) ; si la clé existe dans plusieurs collections, vous obtenez les candidats
list_formats—Les formats et versions que le serveur peut générer, comme GET /formats
get_tokensformat collection?Le projet (ou une collection) sous forme de code généré. Les résultats de plus de 24 000 caractères ne sont pas tronqués — l’outil indique à l’agent comment restreindre par collection. Pour des fichiers complets en CI, utilisez REST et committez le fichier

Le serveur conserve les résultats en mémoire uniquement, revérifie l’API une fois par TTL (30–600 s) et réutilise tout tant que le tampon de fraîcheur du projet ne change pas. Les résultats des outils reprennent les codes d’erreur de l’API (error: unauthorized, error: plan_required, …) ; quand l’API est injoignable, le dernier résultat est servi avec une mention de son ancienneté. Les données des tokens sont encadrées de marqueurs de limite aléatoires, avec un préambule fixe indiquant qu’il s’agit de données, pas d’instructions.

Variables d’environnement :

VariableObligatoireDescription
VARIABLEJAR_TOKEN✓Token d’API du projet (vjt_…) — un token, un projet
VARIABLEJAR_API_URLhttps://variablejar.com/api/v1 (par défaut) ou https://staging.variablejar.com/api/v1 ; tout autre hôte est refusé

Mise à niveau depuis 0.2.0 : cette version appelle un endpoint retiré et reçoit désormais 410. Les noms des outils sont inchangés et les entrées ont seulement été enrichies, mais les sorties ont changé — list_tokens est paginé, avec une première ligne total=… et des clés courtes (c, k, t, v), get_token renvoie les mêmes clés courtes et liste les candidats quand la clé existe dans plusieurs collections, list_collections ne renvoie plus d’identifiants, et get_tokens renvoie un bloc de préambule suivi d’un bloc de code entre marqueurs de limite.

Le serveur est en lecture seule — le token ne peut rien écrire ni supprimer.

Remarques

  • Ne l’appelez pas directement depuis un navigateur (front-end web) — le token serait exposé dans le code client. Utilisez-le depuis des serveurs, des apps ou la CI, où le token reste caché.
  • Les API d’écriture et les requêtes delta (modifications uniquement) ne sont pas encore disponibles.
  • Pour le contexte des LLM, toute la documentation est disponible en /llms.txt (index) et /llms-full.txt (tout dans un seul fichier), en anglais.