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
- variablejar.com/app → menu ⋯ d’une carte de projet → Propriétés → la section Tokens d’API (MCP)
- 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. - 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 :
| format | Sortie | Content-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 mode | text/plain |
compose@1 (alias compose) | Jetpack Compose (Kotlin) — même structure que Swift | text/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ête | Signification |
|---|---|
ETag / If-None-Match | Renvoyez le dernier ETag ; si rien n’a changé, vous obtenez 304 sans corps |
X-VJ-Stamp | Tampon 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-TTL | Secondes à attendre avant de revérifier (30–600) |
X-VJ-Token-Expires | Date d’expiration de ce token |
X-VJ-Contract | Version du contrat d’API (1) |
X-VJ-Format | Format et version d’une réponse ?format=, par ex. css@1 |
Erreurs
Les réponses d’erreur ont pour corps { "error": "<code>" }.
| Statut | Signification |
|---|---|
400 unknown_format · unknown_view · unknown_collection | Valeur de format ou de view inconnue, ou nom de collection absent du projet |
401 unauthorized | Token absent / mal formé / révoqué |
401 token_expired | Le token a expiré — émettez-en un nouveau |
403 token_inactive | La personne qui a émis le token a quitté l’espace de travail ou perdu le rôle nécessaire au token |
403 plan_required | L’offre de l’espace de travail n’inclut pas l’accès à l’API |
403 scope_denied | include=strings exige un token émis avec les valeurs texte |
404 not_found | Mauvais chemin, ou le projet a été supprimé ou mis à la corbeille |
405 method_not_allowed | Méthode autre que GET ou OPTIONS (OPTIONS répond à la requête préliminaire CORS par 204) |
413 too_large | Le 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_outdated | Le client déclaré (X-VJ-Client) est plus ancien que la version minimale acceptée par ce serveur — mettez à jour @variablejar/mcp |
429 rate_limited | Trop de requêtes — réessayez après le nombre de secondes indiqué dans Retry-After |
500 internal | Erreur serveur — si elle persiste après une nouvelle tentative, contactez support@variablejar.com |
502 upstream_unreachable | La passerelle de l’API n’a pas pu joindre le backend — réessayez |
503 not_configured | Le 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 :
| Client | Fichier de configuration |
|---|---|
| Claude Code | .mcp.json à la racine du projet |
| Cursor | .cursor/mcp.json |
| Autres clients MCP | Voir les paramètres de serveurs MCP du client |
Outils disponibles :
| Outil | Entrée | Description |
|---|---|---|
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_tokens | collection? 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_token | key 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_tokens | format 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 :
| Variable | Obligatoire | Description |
|---|---|---|
VARIABLEJAR_TOKEN | ✓ | Token d’API du projet (vjt_…) — un token, un projet |
VARIABLEJAR_API_URL | https://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.