Sandbox API と SDK リファレンス
Lizard SDK は、Lizard (lizard.build) の Sandboxes 用クライアントです: TypeScript と JavaScript 向けには npm の @lizard-build/sdk、Python 向けには PyPI の lizard-sdk(lizard としてインポート)があります。どちらも同じ HTTP API を呼び出します。このページでは、sandbox の各呼び出しを TypeScript と Python の名前で一覧にし、両方の言語の例を示します。手順に沿って最初の実行を試すには クイックスタート を、Sandboxes とは何かについては 概要 を読んでください。
インストールと認証
npm install @lizard-build/sdk
pip install lizard-sdk
export LIZARD_API_KEY="<your-api-key>"Settings → API keys で、または lizard keys create <name> で API キーを作成します。SDK は LIZARD_API_KEY を読み取ります。別のキーを使うには apiKey(Python では api_key)を渡します。各 sandbox にはプロジェクトが必要です。projectId(Python では project_id)、または project に ID、slug、名前を渡します。
作成オプション
| TypeScript | Python |
|---|---|
projectId / project | project_id / project |
timeoutMs | timeout_ms |
region | region |
volumeName / volumeId | volume_name / volume_id |
size | size |
snapshotId | snapshot_id |
envs | envs |
metadata | metadata |
lizardToken | lizard_token |
apiKey | api_key |
import { Sandbox } from '@lizard-build/sdk';
const sandbox = await Sandbox.create('base', {
projectId: 'proj_123',
size: 'small',
timeoutMs: 10 * 60 * 1000,
envs: { MODE: 'test' },
metadata: { task: 'report-42' },
});from lizard import Sandbox
sandbox = Sandbox.create(
"base",
project_id="proj_123",
size="small",
timeout_ms=10 * 60 * 1000,
envs={"MODE": "test"},
metadata={"task": "report-42"},
)- 最初の引数は、ランタイムとテンプレート にあるカタログのテンプレートです。指定しない場合、SDK は
baseを起動します。 sizeは'mini'、'small'、'medium'、'large'のいずれかで、それぞれ 1 vCPU / 2 GB、2 vCPU / 4 GB、4 vCPU / 8 GB (既定)、8 vCPU / 16 GB です。サイズと料金を参照してください。'mini'はbase、claude、codex、interpreterテンプレートからのみ、ボリュームを接続せずに起動できます。トライアル中は'small'が既定で、'medium'は同時に 1 個まで、使えるのは US リージョンだけです。'large'、2 個目の Medium、ほかのリージョンでは HTTP 403 のAuthenticationErrorが投げられます。スナップショットから復元した sandbox にはsizeは適用されず、元の sandbox のサイズで動作します。timeoutMsの既定は 300000(5 分)です。0は期限を無効にします。リソースと有効期間 を参照してください。- 必要に応じてリージョンを指定してください。カタログへの掲載は空き容量を保証しません。ボリュームを接続する場合は
regionを指定しないでください: sandbox はボリュームのある場所で実行されます。 metadataは独自のラベルです。getInfo()はこれを返しますが、list()は返しません。lizardTokenは自分のliz_API キーを 1 つ受け取り、sandbox 内のlizardをサインインさせます。自分のキーはリクエストを許可するためだけに使います。sandbox には、sandbox のプロジェクトに限定され sandbox と一緒に削除される専用の新しいキーが渡されるため、そこでのlizardはそのプロジェクトにしか作用しません。baseテンプレートにはlizardがありません。
メソッド
| TypeScript | Python | 機能 |
|---|---|---|
Sandbox.create(template, options) | Sandbox.create(template, ...) | カタログのテンプレートからプロジェクト内に作成。 |
Sandbox.connect(sandboxId) | Sandbox.connect(sandbox_id) | 既存の sandbox に接続。自動再開はしません。 |
Sandbox.list({ projectId }) | Sandbox.list(project_id=...) | アクセスできる Sandboxes を一覧表示。状態を確認してください。 |
sandbox.getInfo() | sandbox.get_info() | 状態、ランタイム、メタデータを取得。 |
sandbox.process.exec(cmd, opts) | sandbox.process.exec_(cmd, ...) | シェルコマンドまたは argv 配列を実行し、stdout、stderr、終了コードを返す。 |
sandbox.process.list() | sandbox.process.list() | exec で起動したプロセスを一覧表示。 |
sandbox.process.kill(pid, signal) | sandbox.process.kill(pid, signal) | プロセスとその子プロセスにシグナルを送る。既定は SIGTERM。 |
sandbox.fs.write(path, data) | sandbox.fs.write(path, data) | テキストまたはバイトを書き込み、親ディレクトリを作成。 |
sandbox.fs.read(path) | sandbox.fs.read(path) | UTF-8 テキストを読み取る。 |
sandbox.fs.readBytes(path) | sandbox.fs.read_bytes(path) | ファイルのバイトを読み取る。 |
sandbox.fs.list(path) | sandbox.fs.list(path) | ディレクトリの項目を一覧表示。 |
sandbox.fs.stat(path) | sandbox.fs.stat(path) | 種類、サイズ、モード、所有者、更新日時を返す。 |
sandbox.fs.makeDir(path) | sandbox.fs.make_dir(path) | ディレクトリと不足する親を作成。 |
sandbox.fs.move(from, to) | sandbox.fs.move(src, dst) | ファイルまたはディレクトリを移動。 |
sandbox.fs.remove(path) | sandbox.fs.remove(path) | ファイルまたはディレクトリを削除。 |
sandbox.exposePort(port) | sandbox.expose_port(port) | ポートを公開し、url、hostname、アクセストークンを返す。 |
sandbox.getHost(port) | sandbox.get_host(port) | ポートを公開してホスト名を返す。リクエストには sandbox.accessToken が必要。 |
sandbox.unexpose(port) | sandbox.unexpose(port) | 公開したポートを削除。 |
sandbox.setTimeout(ms) | sandbox.set_timeout(ms) | 残りの有効期間を設定。最小 1000 ミリ秒。 |
sandbox.pause() / sandbox.resume() | sandbox.pause() / sandbox.resume() | 一時停止または再開をキューに入れ、すぐに戻る。 |
sandbox.pause({ fast: true }) | sandbox.pause(fast=True) | ファイルだけを保持して一時停止します。メモリのサイズにかかわらず約 1 秒です。プロセスは終了し、再開時にサンドボックスは新しく起動します。 |
sandbox.waitForStatus(status) | sandbox.wait_for_status(status) | paused または running を待つ。一時停止に失敗した場合はエラーを投げる。 |
sandbox.fork({ count }) | sandbox.fork(count=...) | 実行中の sandbox を、メモリとプロセスを含めて 1~100 個コピー。各コピーは実行中の sandbox の上限に数えられる。 |
sandbox.snapshot(name) | sandbox.snapshot(name) | メモリ、プロセス、すべてのファイルをスナップショットとして保存。復元できるのは、この sandbox と同じプロジェクトとリージョンだけ。 |
Sandbox.waitForSnapshot(snapshotId) | Sandbox.wait_for_snapshot(snapshot_id) | スナップショットの準備完了を待つ。 |
Sandbox.restore(snapshotId, { projectId, volumeId, timeoutMs }) | Sandbox.restore(snapshot_id, project_id=..., volume_id=..., timeout_ms=...) | スナップショットと同じプロジェクトとリージョンに新しい sandbox を起動。ほかの projectId では、code が SNAPSHOT_SCOPE の AuthenticationError(HTTP 403)を投げる。 |
Sandbox.snapshots(projectId) | Sandbox.snapshots(project_id) | プロジェクトで作成したスナップショットを一覧表示。 |
Sandbox.mySnapshots() | Sandbox.my_snapshots() | 自分が作成したすべてのスナップショットを、すべてのワークスペースから一覧表示。 |
Sandbox.deleteSnapshot(snapshotId) | Sandbox.delete_snapshot(snapshot_id) | スナップショットを削除。そこから復元した sandbox は実行を続ける。 |
sandbox.kill() | sandbox.kill() | sandbox を停止し、ボリュームを切り離す。 |
コマンドを実行する
process.exec(Python では exec_)はコマンドを実行し、終了するまで待ちます。コマンドの実行中に出力を受け取るには、onStdout または onStderr(Python では on_stdout、on_stderr)を渡します。1 回の呼び出しで、末尾の改行を除いた 1 行が届きます。その場合も、呼び出しは最後に結果全体を返します。文字列の代わりに argv 配列を渡すとシェルを経由しません。信頼できないテキストを引数として渡すには、これが安全な方法です。
const result = await sandbox.process.exec('npm test', {
workdir: '/app',
envs: { NODE_ENV: 'test' },
timeoutMs: 120_000,
onStdout: (line) => console.log(line),
});
if (result.exitCode !== 0) throw new Error(result.stderr);
await sandbox.process.exec(['grep', '-rn', '--', userQuery, '/workspace']);result = sandbox.process.exec_(
"npm test",
workdir="/app",
envs={"NODE_ENV": "test"},
timeout_ms=120_000,
on_stdout=print,
)
if result.exit_code != 0:
raise RuntimeError(result.stderr)
sandbox.process.exec_(["grep", "-rn", "--", user_query, "/workspace"])コマンドの結果には stdout、stderr、終了コードが含まれます。0 以外の終了コードは自分で確認する結果であり、リクエストの失敗は例外を投げます。timeoutMs(Python では timeout_ms)は、コマンドを実行できる時間を 1~600 秒で設定します。指定しない場合、サーバーは 150 秒後にコマンドを止め、TypeScript SDK は 60 秒後に待つのをやめて、TimeoutError という名前の DOMException を投げます。1 分より長くかかる可能性があるコマンドには timeoutMs を渡してください。process.exec は envs、workdir、user を受け付けます。user を渡さない限り、コマンドは root として実行されます。作成時の envs はすべてのコマンドに渡されます。
ファイル
fs.write はテキストまたはバイトを書き込み、fs.read はテキストを読み取ります。バイナリファイルはバイトとして書き込み、fs.readBytes(Python では read_bytes)で読み戻します。絶対パスを使ってください。存在しないパスは NotFoundError を投げます。
await sandbox.fs.write('/app/data.csv', 'x,y\n1,2\n');
const text = await sandbox.fs.read('/app/data.csv');
const entries = await sandbox.fs.list('/app');
const png = await sandbox.fs.readBytes('/app/chart.png');sandbox.fs.write("/app/data.csv", "x,y\n1,2\n")
text = sandbox.fs.read("/app/data.csv")
entries = sandbox.fs.list("/app")
png = sandbox.fs.read_bytes("/app/chart.png")一時停止とスナップショットは、どこに書いたファイルでもディスク上のすべてを保持します。停止(kill または期限切れ)後は、/workspace の Persistent Volumes 以外にあるファイルは消えます。事前にスナップショットを作成した場合は除きます。
ポート
sandbox 内で 0.0.0.0 上のサーバーを起動し、そのポートを公開します。すべてのリクエストにはアクセストークンが必要です。X-Lizard-Access-Token ヘッダーで送るか、ブラウザーでは一度だけ ?lizard_token= として渡します。プレビュー URL を参照してください。
const { url, hostname, accessToken } = await sandbox.exposePort(3000);
console.log(url); // open in a browser; it carries the token
await fetch(`https://${hostname}/api`, { headers: { 'X-Lizard-Access-Token': accessToken } });
await sandbox.unexpose(3000);import httpx
exposed = sandbox.expose_port(3000)
print(exposed.url) # open in a browser; it carries the token
httpx.get(f"https://{exposed.hostname}/api", headers={"X-Lizard-Access-Token": exposed.access_token})
sandbox.unexpose(3000)一時停止、スナップショット、fork
これらの呼び出しは、メモリ、実行中のプロセス、ファイルを保持します。それぞれで何が保持されるか、誰がスナップショットを復元できるか、復元がどう課金されるか、何が失敗するかは クイックスタート で説明しています。
await sandbox.pause();
await sandbox.waitForStatus('paused');
await sandbox.resume();
await sandbox.waitForStatus('running');
const saved = await sandbox.snapshot('ready-env');
const copy = await Sandbox.restore(saved.id);
for (const f of await sandbox.fork({ count: 2 })) {
if (f.sandbox) await f.sandbox.process.exec('echo hi');
else console.warn('fork failed:', f.error);
}sandbox.pause()
sandbox.wait_for_status("paused")
sandbox.resume()
sandbox.wait_for_status("running")
saved = sandbox.snapshot("ready-env")
copy = Sandbox.restore(saved["id"])
for f in sandbox.fork(count=2):
if f.sandbox:
f.sandbox.process.exec_("echo hi")
else:
print("fork failed:", f.error)fork はコピーごとに 1 つのエントリを返します: 新しい sandbox、またはアカウントの sandbox 上限などのエラーです。各コピーは元の sandbox と同じように課金されます。
状態を保持してコードを実行する
CodeSandbox は interpreter テンプレートを起動し、runCode(Python では run_code)でコードを実行します。このテンプレートでは、Python はコンテキストごとに状態を保持する Jupyter カーネルで実行されるため、変数は呼び出し間で引き継がれ、結果に image/png のグラフを含めることができます。JavaScript と bash は、呼び出しごとに新しいプロセスとして実行されます。コードインタープリターを参照してください。
ボリューム
sandbox 間で /workspace を保持するには、Persistent Volumes を名前で接続します:
import { Sandbox, Volume } from '@lizard-build/sdk';
await Volume.getOrCreate('proj_123', 'agent-workdir', { sizeGb: 10 });
const sandbox = await Sandbox.create('base', { projectId: 'proj_123', volumeName: 'agent-workdir' });from lizard import Sandbox, Volume
Volume.get_or_create("proj_123", "agent-workdir", size_gb=10)
sandbox = Sandbox.create("base", project_id="proj_123", volume_name="agent-workdir")未対応の API
ファイル監視はまだ利用できません。sandbox.fork() は、ボリュームが接続されている場合は 409 を返します。Sandbox.connect は一時停止中や停止済みの sandbox を再開しません。一時停止中の sandbox には resume() を呼び出してください。SSH プロトコルでのアクセスはできません。lizard sandbox ssh は CLI の認証情報で対話型シェルを開きます。
エラー
API の失敗時には、以下のエラーが投げられます(Python では raise されます)。各エラーは HTTP ステータスと、API が送った場合は code を持ちます。
| エラー | 意味 |
|---|---|
PaymentRequiredError | HTTP 402: 何かを作成する前に、アカウントで Pro を開始するか請求書を支払う必要があります。url は開くべきページです。 |
AuthenticationError | HTTP 401 または 403: キーが無効か、アクセス権がありません。トライアル中に 2 台目の Medium の sandbox を同時に動かそうとした場合や US 以外のリージョンを指定した場合も 403 になり、code は TRIAL_MEDIUM_RUNNING または TRIAL_SANDBOX_REGION です。Large の sandbox を作成、再開、fork したときは、どれも SANDBOX_SIZE_NOT_ALLOWED 付きの 403 になります。 |
NotFoundError | HTTP 404: sandbox、ファイル、スナップショットが存在しないか、期限切れです。 |
ConflictError | HTTP 409: ボリュームが接続された sandbox の fork など、状態の競合。 |
LimitExceededError | HTTP 429: 同時に実行する sandbox の vCPU が多すぎるか、起動が多すぎます。code はどの上限かを示します(SANDBOX_LIMIT_REACHED や SANDBOX_RATE_LIMITED など)。SANDBOX_LIMIT_REACHED では、limit と running は vCPU 単位で、unit がそれを示し(vcpu)、needed は拒否された sandbox に必要な vCPU です。retryAfterS(Python では retry_after_s)は再試行できるまでの時間を示します。 |
TimeoutError | HTTP 408 または 504。process.exec に対する TypeScript SDK 自身の 60 秒の待機では、代わりに TimeoutError という名前の DOMException を投げます。 |
LizardError | 未対応の操作を含む、その他の API の失敗。 |
HTTP 429 の基準となる数値は アカウントの上限 にあります。
HTTP API
SDK は https://lizard.build にある Lizard の REST API を呼び出します。API キーは Authorization: Bearer liz_... として、または X-API-Key ヘッダーで送ります。
| 呼び出し | リクエスト |
|---|---|
| 作成 | template、projectId、size、timeoutMs、envs、metadata、region、volumeName を指定して POST /api/sandboxes。sandboxId 付きで 201 を返します |
| 状態の取得 | GET /api/sandboxes/{id} |
| 一覧 | GET /api/sandboxes、または 1 つのプロジェクトについては GET /api/projects/{projectId}/sandboxes |
| コマンドの実行 | cmd、envs、workdir、user、timeoutMs を指定して POST /api/sandboxes/{id}/exec。stdout、stderr、exitCode を返します |
| 有効期間の変更 | timeoutMs を指定して POST /api/sandboxes/{id}/timeout |
| 一時停止または再開 | POST /api/sandboxes/{id}/pause、POST /api/sandboxes/{id}/resume |
| ポートの公開 | POST /api/sandboxes/{id}/expose/{port}。同じパスへの DELETE で削除します |
| 停止 | DELETE /api/sandboxes/{id} |
| 上限の確認 | GET /api/sandboxes/limits。tier、unit、limits、running、runningVcpu を返します |
curl -X POST https://lizard.build/api/sandboxes \
-H "Authorization: Bearer $LIZARD_API_KEY" \
-H "Content-Type: application/json" \
-d '{"template": "base", "projectId": "proj_123", "timeoutMs": 300000}'直接の API は、timeoutMs を渡さない限り、期限なしで sandbox を作成します。
保存と課金
課金、送信トラフィック、停止後に何が残るかは、保存と課金 にまとめています。サイズと時間単価は 制限 にあります。
更新日