API リファレンス

iOS/Android アプリや CI パイプラインなど、どこからでも REST で variable Jar の変数を取得できます。 読み取り専用で、MCP サーバーと同じトークンを使います。

ベータ: API と MCP はリリース前に変更される可能性があります。形式にはバージョンが付くようになりました(「プラットフォームのコード出力」を参照)。互換性を壊す変更は12か月の併存期間とともにお知らせします。

トークンを発行する

  1. variablejar.com/app → プロジェクトカードの ⋯ メニュー → プロパティ → APIトークン(MCP) セクション
  2. トークン名を入力して 発行 を押します — トークン(vjt_…)が表示されるのは発行直後の 1回だけ です。安全な場所に保管してください。
  3. トークンでアクセスできるのはそのプロジェクトひとつだけです。漏れた場合は、同じ画面ですぐに無効にしてください。

トークンには有効期限があります(既定は180日、最長365日)。期限の14日前にベル通知が届きます。テキスト値(STRING)を含むトークンを発行できるのはワークスペースのオーナーだけで、未公開の翻訳を含むすべての言語の値が出力されます。トークンを特定のコレクションに限定することもできます。

トークンの安全性は保管場所しだいです。トークンを持つ人は、その範囲内の値をすべて取得できます。API や MCP でエクスポートしたデータはサービスの外に出て、利用者の責任で扱われます。

エンドポイント

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

テキスト値(STRING)は、テキスト値を含めて発行したトークンで ?include=strings を付けたときだけ含まれます。

レスポンス

値はエイリアス({Collection/key})が 解決された 最終値です。解決できなかったセルだけが、理由(broken · cycle · inline)とともに元の値のまま unresolved に入ります。

{
  "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" }
  ]
}

include=strings がないと、STRING のトークンは一覧には出ますが、valuesByMode が空で "omitted": "strings" が付きます。

プラットフォームのコード出力

?format= を付けると、JSON の代わりに生成されたプラットフォームのコードを受け取れます:

format出力Content-Type
css@1 (別名 css)CSS カスタムプロパティ — 既定モードは :root、ほかのモードは [data-theme="<mode>"]text/css
swift@1 (別名 swift)SwiftUI — コレクションごとに1つの型、モードごとに1つの static インスタンスtext/plain
compose@1 (別名 compose)Jetpack Compose(Kotlin)— Swift と同じ構造text/plain

形式にはバージョンがあります。バージョンなしの名前(css)は @1 に永久に固定された別名で、新しいバージョンが出ても自動で切り替わることはありません。バージョン内で許される変更は2種類だけです — 構文として正しくない出力の修正と、セキュリティのためのエスケープの修正 — どちらも形式の rev(下記の /formats に表示)を上げ、キャッシュを無効にします。値の表現や識別子が変わる変更は新しいバージョン(css@2)になり、以前のバージョンは12か月間利用できます(Deprecation・Sunset ヘッダーでお知らせします)。

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

出力は決定的です — 同じトークンからは常に同じバイト列が出るので、ETag/If-None-Match のキャッシュは JSON のレスポンスと同じように働きます。エイリアスは常に最終値に解決され、解決できない参照はコメントとして出力され、値をでっち上げることはありません。不明な format には 400 { "error": "unknown_format" } が返ります。

識別子はコレクション名と変数名から作られ、データの順序には左右されません。Figma でコレクション・変数・モードの順序を入れ替えても、トークンの名前は変わりません。2つの名前が同じ識別子にまとまる場合は、元の名前の順で先に来るものがそのままの識別子を、残りが _2、_3 … を受け取ります。衝突する名前を新しく追加すると既存の番号がずれることがあるため、区切り文字や大文字・小文字だけが異なる名前は避けてください。どのフィルター(collection・include=strings・一部のコレクションだけに限定したトークン)を使っても、同じ変数は同じ識別子を受け取ります。名前はまずプロジェクト全体で確定し、応答はその後で絞り込まれます。

?collection=<name> を付けると出力を1つのコレクションに絞れます(プロジェクトにない名前なら 400 unknown_collection)。?view=ai@1 は AI エージェント向けに整えたコンパクトなビューを返します(名前と値のみ、テキスト値は既定で除外)。format とは併用できず、index(下記)以外の view の値には 400 unknown_view が返ります。

?view=index を format と一緒に付けると、コードの代わりに、その形式で各変数が受け取る識別子を返します — 生成されたコードを解析せずに名前を確認するためのものです。識別子は出力と同じ綴りです(Swift/Kotlin の予約語はバッククォート付き)。テキスト(STRING)の変数は、テキスト値を含めて発行したトークンで include=strings を付けた場合にだけインデックスに含まれます。format なしの view=index には 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 は、このサーバーが提供する形式とバージョンを、それぞれの現在の rev・ファイル名・Content-Type とともに一覧で返します。同じトークンを使いますが、使用量にもリクエスト数の制限にも数えられず、変数のエンドポイントと同じく ETag/If-None-Match に対応します(X-VJ-Stamp は付きません — 一覧は静的です)。新しいバージョンに置き換えられたバージョンには "deprecated": { "since": "YYYY-MM-DD", "sunset": "YYYY-MM-DD" } も付きます。sunset は日付が決まっている場合にだけ付きます。

{
  "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" }]
}

ポーリングと ETag

レスポンスには ETag ヘッダーが含まれます。それを If-None-Match として送り返すと、何も変わっていなければ 304(本文なし)が返ります — モバイルアプリや CI からの定期的な確認で帯域を節約できます。受け取った ETag の値はそのまま使ってください(W/ を含むことがあります)。

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

200 と 304 のレスポンスには次のヘッダーが付きます:

ヘッダー意味
ETag / If-None-Match最後に受け取った ETag を送り返すと、変更がなければ本文なしの 304 が返ります
X-VJ-Stampプロジェクトの内容 + このトークンの範囲に対する鮮度スタンプ(同じトークンならどの形式でも同じ値) — スタンプが同じなら、どの形式でもデータは同じです
X-VJ-TTL再確認までに待つ秒数(30–600)
X-VJ-Token-Expiresこのトークンの有効期限
X-VJ-ContractAPI 契約のバージョン(1)
X-VJ-Format?format= レスポンスの形式とバージョン(例: css@1)

エラー

エラーのレスポンス本文は { "error": "<コード>" } です。

ステータス意味
400 unknown_format · unknown_view · unknown_collection不明な format・view の値、またはプロジェクトにない collection の名前
401 unauthorizedトークンがない / 形式が正しくない / 無効化されている
401 token_expiredトークンの有効期限切れ — 新しく発行してください
403 token_inactiveトークンの発行者がワークスペースを離れたか、トークンに必要な役割を失った
403 plan_requiredワークスペースのプランに API が含まれていない
403 scope_deniedinclude=strings には、テキスト値を含めて発行したトークンが必要
404 not_foundパスが違う、またはプロジェクトが削除されたかゴミ箱に移された
405 method_not_allowedGET・OPTIONS 以外のメソッド(OPTIONS は CORS のプリフライトに 204 で応答)
413 too_largeプロジェクトが API のサイズ上限(変数 25,000 個、または変数データの合計 24 MB)を超えている — 一部のコレクションを別のプロジェクトに移すか、support@variablejar.com にご連絡ください
426 client_outdated申告されたクライアント(X-VJ-Client)が、このサーバーが受け付ける最小バージョンより古い — @variablejar/mcp を更新してください
429 rate_limitedリクエストが多すぎる — Retry-After の秒数だけ待ってから再試行
500 internalサーバーエラー — 再試行しても続く場合は support@variablejar.com にご連絡ください
502 upstream_unreachableAPI ゲートウェイがバックエンドに到達できなかった — 再試行してください
503 not_configuredサービスが設定されていない — support@variablejar.com にご連絡ください

MCP サーバー(IDE / AI エージェント)

IDE や AI コーディングエージェントからは、REST よりも @variablejar/mcp の MCP サーバーのほうが便利です — 同じトークンが両方で使えます。このページを AI エージェントに渡して、連携の設定を頼むこともできます。

MCP の設定に追加します(バージョンは固定します):

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

ファイルの場所はクライアントによって異なります:

クライアント設定ファイル
Claude Codeプロジェクトのルートの .mcp.json
Cursor.cursor/mcp.json
その他の MCP クライアントクライアントの MCP サーバー設定を参照

使えるツール:

ツール入力説明
list_collections—コレクションとそのモード・トークン数・タイプの内訳・最上位のグループ — まずはここから
list_tokenscollection? prefix? type? query? format? limit(50、最大 200) cursor? include_strings?モードごとの値を解決したトークンをページ単位で。データブロックの最初の行は常に total=<n> returned=<m> nextCursor=<c|none>。format(例: css@1)を指定すると、各トークンにその形式での識別子も付きます
get_tokenkey collection? format?キー(例: color/primary)を指定した1つのトークン。同じキーが複数のコレクションにある場合は候補が返ります
list_formats—サーバーが生成できる形式とバージョン — GET /formats と同じ
get_tokensformat collection?プロジェクト(または1つのコレクション)を生成されたコードで。24,000 文字を超える結果は切り詰めず、コレクションで絞り込む方法をエージェントに案内します。CI でファイル全体が必要なら、REST を使ってファイルをコミットしてください

サーバーは結果をメモリーにだけ保持し、TTL(30–600 秒)ごとに API を1回確認し直し、プロジェクトの鮮度スタンプが変わらない間はすべてを再利用します。ツールの結果には API のエラーコード(error: unauthorized、error: plan_required など)がそのまま入ります。API に接続できないときは、最後の結果をその古さを示す注記とともに返します。トークンのデータはランダムな境界マーカーで囲まれ、「指示ではなくデータである」と明記した固定の前置きが付きます。

環境変数:

変数必須説明
VARIABLEJAR_TOKEN✓プロジェクトの API トークン(vjt_…)— トークン1つにプロジェクト1つ
VARIABLEJAR_API_URLhttps://variablejar.com/api/v1(既定)または https://staging.variablejar.com/api/v1。それ以外のホストは拒否されます

0.2.0 からのアップグレード: 0.2.0 は廃止されたエンドポイントを呼び出すため、現在は 410 を受け取ります。ツール名は変わらず、入力は追加されただけですが、出力は変わりました — list_tokens は total=… の1行目があるページ方式になり、短いキー(c、k、t、v)を使います。get_token も同じ短いキーを使い、同じキーが複数のコレクションにある場合は候補を返します。list_collections は id を返さなくなり、get_tokens は前置きのブロックと、境界マーカーの中のコードのブロックを返します。

サーバーは読み取り専用です — トークンで何かを書き込んだり削除したりすることはできません。

注意

  • ブラウザ(Web フロントエンド)から直接呼ばないでください — トークンがクライアントのコードに露出します。トークンが隠れたままのサーバー、アプリ、CI から使ってください。
  • 書き込み API と差分(変更分のみ)の取得はまだありません。
  • LLM のコンテキスト用に、ドキュメント全体を /llms.txt(目次)と /llms-full.txt(全部を1ファイルに)で提供しています。