Install
pip install gravixlayer
npm install gravixlayer
API key
Create a key at API keys in the console. Copy it when it appears. You cannot view it again.export GRAVIXLAYER_API_KEY="your-api-key"
GRAVIXLAYER_API_KEY. gravixlayer auth login stores the same key in your OS keychain. Requests use Authorization: Bearer against https://api.gravixlayer.ai.
GravixLayer() defaults to cloud=aws, region=us-east-1. create() defaults to template=base-small.
Create your first sandbox
from gravixlayer import GravixLayer
client = GravixLayer() # defaults to cloud="aws", region="us-east-1"
sandbox = client.runtime.create() # defaults to template="base-small"
print(f"Runtime: {sandbox.runtime_id} ({sandbox.status})")
result = sandbox.run_code(code="print('Hello from Gravix Layer!')")
print(result.text)
sandbox.kill()
import { GravixLayer } from 'gravixlayer';
const client = new GravixLayer(); // defaults to cloud="aws", region="us-east-1"
const sandbox = await client.runtime.create(); // defaults to template="base-small"
console.log(`Runtime: ${sandbox.runtimeId} (${sandbox.status})`);
const result = await sandbox.runCode("print('Hello from Gravix Layer!')");
console.log(result.text);
await sandbox.kill();
# Requires: GRAVIXLAYER_API_KEY, jq
# Defaults: template=base-small, cloud=aws, region=us-east-1
RT=$(gravixlayer runtime create --wait --output json | jq -r '.runtime_id')
echo "Runtime: $RT"
# Run code inline — no file needed
gravixlayer runtime run "$RT" --code 'print("Hello from Gravix Layer!")'
gravixlayer runtime kill "$RT" -y
# Requires: GRAVIXLAYER_API_KEY, jq
API="https://api.gravixlayer.ai/v1"
AUTH=(-H "Authorization: Bearer $GRAVIXLAYER_API_KEY" -H "Content-Type: application/json")
RT=$(curl -sS -X POST "$API/agents/runtime" "${AUTH[@]}" \
-d '{"template":"base-small","cloud":"aws","region":"us-east-1"}' | jq -r '.runtime_id')
for i in $(seq 1 60); do
STATUS=$(curl -sS "$API/agents/runtime/$RT" -H "Authorization: Bearer $GRAVIXLAYER_API_KEY" | jq -r '.status')
[ "$STATUS" = "running" ] && break
sleep 2
done
curl -sS -X POST "$API/agents/runtime/$RT/code/run" "${AUTH[@]}" \
-d '{"code":"print(\"Hello from Gravix Layer!\")","language":"python"}'
echo
curl -sS -X DELETE "$API/agents/runtime/$RT" -H "Authorization: Bearer $GRAVIXLAYER_API_KEY"
echo
Run a command
from gravixlayer import GravixLayer
client = GravixLayer() # defaults to cloud="aws", region="us-east-1"
sandbox = client.runtime.create() # defaults to template="base-small"
cmd = sandbox.run_cmd(command="python", args=["--version"])
print(cmd.stdout)
sandbox.kill()
import { GravixLayer } from 'gravixlayer';
const client = new GravixLayer(); // defaults to cloud="aws", region="us-east-1"
const sandbox = await client.runtime.create(); // defaults to template="base-small"
const cmd = await sandbox.runCmd('python', { args: ['--version'] });
console.log(cmd.stdout);
await sandbox.kill();
RT=$(gravixlayer runtime create --wait --output json | jq -r '.runtime_id')
gravixlayer runtime exec "$RT" python --version
gravixlayer runtime kill "$RT" -y
API="https://api.gravixlayer.ai/v1"
AUTH=(-H "Authorization: Bearer $GRAVIXLAYER_API_KEY" -H "Content-Type: application/json")
RT=$(curl -sS -X POST "$API/agents/runtime" "${AUTH[@]}" \
-d '{"template":"base-small","cloud":"aws","region":"us-east-1"}' | jq -r '.runtime_id')
for i in $(seq 1 60); do
STATUS=$(curl -sS "$API/agents/runtime/$RT" -H "Authorization: Bearer $GRAVIXLAYER_API_KEY" | jq -r '.status')
[ "$STATUS" = "running" ] && break
sleep 2
done
curl -sS -X POST "$API/agents/runtime/$RT/commands/run" "${AUTH[@]}" \
-d '{"command":"python","args":["--version"],"timeout":300000}'
echo
curl -sS -X DELETE "$API/agents/runtime/$RT" -H "Authorization: Bearer $GRAVIXLAYER_API_KEY"
echo
Write and read files
from gravixlayer import GravixLayer
client = GravixLayer() # defaults to cloud="aws", region="us-east-1"
sandbox = client.runtime.create() # defaults to template="base-small"
sandbox.file.write("/workspace/hello.txt", "Hello World\n")
print(sandbox.file.read("/workspace/hello.txt").content)
sandbox.kill()
import { GravixLayer } from 'gravixlayer';
const client = new GravixLayer(); // defaults to cloud="aws", region="us-east-1"
const sandbox = await client.runtime.create(); // defaults to template="base-small"
await sandbox.file.write('/workspace/hello.txt', 'Hello World\n');
console.log((await sandbox.file.read('/workspace/hello.txt')).content);
await sandbox.kill();
RT=$(gravixlayer runtime create --wait --output json | jq -r '.runtime_id')
printf 'Hello World\n' | gravixlayer runtime files write "$RT" /workspace/hello.txt
gravixlayer runtime files cat "$RT" /workspace/hello.txt
gravixlayer runtime kill "$RT" -y
API="https://api.gravixlayer.ai/v1"
AUTH=(-H "Authorization: Bearer $GRAVIXLAYER_API_KEY" -H "Content-Type: application/json")
RT=$(curl -sS -X POST "$API/agents/runtime" "${AUTH[@]}" \
-d '{"template":"base-small","cloud":"aws","region":"us-east-1"}' | jq -r '.runtime_id')
for i in $(seq 1 60); do
STATUS=$(curl -sS "$API/agents/runtime/$RT" -H "Authorization: Bearer $GRAVIXLAYER_API_KEY" | jq -r '.status')
[ "$STATUS" = "running" ] && break
sleep 2
done
curl -sS -X POST "$API/agents/runtime/$RT/files/write" "${AUTH[@]}" \
-d '{"path":"/workspace/hello.txt","content":"Hello World\n"}'
echo
curl -sS -X POST "$API/agents/runtime/$RT/files/read" "${AUTH[@]}" \
-d '{"path":"/workspace/hello.txt"}'
echo
curl -sS -X DELETE "$API/agents/runtime/$RT" -H "Authorization: Bearer $GRAVIXLAYER_API_KEY"
echo
Use secrets
Create secrets under an Identity provider, attach them to the sandbox, and read them as environment variables inrun_code / run_cmd.
from gravixlayer import GravixLayer
client = GravixLayer() # defaults to cloud="aws", region="us-east-1"
provider = client.identity.providers.create(
name="OpenAI",
provider_type="api_key",
secrets=[{"key": "OPENAI_API_KEY", "value": "sk-..."}],
)
sandbox = client.runtime.create(providers=[provider.id]) # defaults to template="base-small"
result = sandbox.run_code(
code="import os; print('ok' if os.environ.get('OPENAI_API_KEY') else 'missing')"
)
print(result.text)
sandbox.kill()
client.identity.providers.delete(provider.id)
import { GravixLayer } from 'gravixlayer';
const client = new GravixLayer(); // defaults to cloud="aws", region="us-east-1"
const provider = await client.identity.providers.create('OpenAI', {
providerType: 'api_key',
secrets: [{ key: 'OPENAI_API_KEY', value: 'sk-...' }],
});
const sandbox = await client.runtime.create({ providers: [provider.id] }); // defaults to template="base-small"
const result = await sandbox.runCode(
"import os; print('ok' if os.environ.get('OPENAI_API_KEY') else 'missing')",
);
console.log(result.text);
await sandbox.kill();
await client.identity.providers.delete(provider.id);
# Requires: GRAVIXLAYER_API_KEY, jq
PROVIDER_ID=$(gravixlayer provider create "OpenAI" --type api_key \
--secret "OPENAI_API_KEY=sk-..." \
--output json | jq -r '.id // .provider.id')
RT=$(gravixlayer runtime create \
--provider "$PROVIDER_ID" \
--wait --output json | jq -r '.runtime_id')
echo 'import os; print("ok" if os.environ.get("OPENAI_API_KEY") else "missing")' > /tmp/check_secret.py
gravixlayer runtime run "$RT" /tmp/check_secret.py
gravixlayer runtime kill "$RT" -y
gravixlayer provider delete "$PROVIDER_ID" -y
API="https://api.gravixlayer.ai/v1"
AUTH=(-H "Authorization: Bearer $GRAVIXLAYER_API_KEY" -H "Content-Type: application/json")
PROVIDER_ID=$(curl -sS -X POST "$API/identity/providers" "${AUTH[@]}" \
-d '{
"name": "OpenAI",
"provider_type": "api_key",
"secrets": [{"key": "OPENAI_API_KEY", "value": "sk-..."}]
}' | jq -r '.id // .provider.id')
RT=$(curl -sS -X POST "$API/agents/runtime" "${AUTH[@]}" \
-d "{
\"template\": \"base-small\",
\"cloud\": \"aws\",
\"region\": \"us-east-1\",
\"providers\": [\"$PROVIDER_ID\"]
}" | jq -r '.runtime_id')
for i in $(seq 1 60); do
STATUS=$(curl -sS "$API/agents/runtime/$RT" -H "Authorization: Bearer $GRAVIXLAYER_API_KEY" | jq -r '.status')
[ "$STATUS" = "running" ] && break
sleep 2
done
curl -sS -X POST "$API/agents/runtime/$RT/code/run" "${AUTH[@]}" \
-d '{"code":"import os; print(\"ok\" if os.environ.get(\"OPENAI_API_KEY\") else \"missing\")","language":"python"}'
echo
curl -sS -X DELETE "$API/agents/runtime/$RT" -H "Authorization: Bearer $GRAVIXLAYER_API_KEY"
curl -sS -X DELETE "$API/identity/providers/$PROVIDER_ID" -H "Authorization: Bearer $GRAVIXLAYER_API_KEY"
echo
Limit outbound network
By default a new sandbox cannot reach the public internet. Attach a network policy (for example an allowlist) to open only the destinations you need.from gravixlayer import GravixLayer
client = GravixLayer() # defaults to cloud="aws", region="us-east-1"
policy = client.network_policies.create(
name="openai-only",
egress_mode="allowlist",
rules=[{"destination": "api.openai.com", "port": 443, "protocol": "tcp"}],
)
sandbox = client.runtime.create(network_policy_ids=[policy.id]) # defaults to template="base-small"
sandbox.kill()
client.network_policies.delete(policy.id)
import { GravixLayer } from 'gravixlayer';
const client = new GravixLayer(); // defaults to cloud="aws", region="us-east-1"
const policy = await client.networkPolicies.create('openai-only', {
egressMode: 'allowlist',
rules: [{ destination: 'api.openai.com', port: 443, protocol: 'tcp' }],
});
const sandbox = await client.runtime.create({ networkPolicyIds: [policy.id] }); // defaults to template="base-small"
await sandbox.kill();
await client.networkPolicies.delete(policy.id);
# Requires: GRAVIXLAYER_API_KEY, jq
# CLI create is policy-only; add rules with add-rule (SDK can create+rules in one call).
POLICY_ID=$(gravixlayer network-policy create "openai-only" \
--egress-mode allowlist \
--output json | jq -r '.id')
gravixlayer network-policy add-rule "$POLICY_ID" \
--destination api.openai.com --port 443 --protocol tcp
RT=$(gravixlayer runtime create \
--network-policy "$POLICY_ID" \
--wait --output json | jq -r '.runtime_id')
gravixlayer runtime kill "$RT" -y
gravixlayer network-policy delete "$POLICY_ID" -y
API="https://api.gravixlayer.ai/v1"
AUTH=(-H "Authorization: Bearer $GRAVIXLAYER_API_KEY" -H "Content-Type: application/json")
POLICY_ID=$(curl -sS -X POST "$API/network-policies" "${AUTH[@]}" \
-d '{
"name": "openai-only",
"egress_mode": "allowlist"
}' | jq -r '.id')
curl -sS -X POST "$API/network-policies/$POLICY_ID/rules" "${AUTH[@]}" \
-d '{"destination":"api.openai.com","port":443,"protocol":"tcp"}'
echo
RT=$(curl -sS -X POST "$API/agents/runtime" "${AUTH[@]}" \
-d "{
\"template\": \"base-small\",
\"cloud\": \"aws\",
\"region\": \"us-east-1\",
\"network_policy_ids\": [\"$POLICY_ID\"]
}" | jq -r '.runtime_id')
curl -sS -X DELETE "$API/agents/runtime/$RT" -H "Authorization: Bearer $GRAVIXLAYER_API_KEY"
curl -sS -X DELETE "$API/network-policies/$POLICY_ID" -H "Authorization: Bearer $GRAVIXLAYER_API_KEY"
echo
What’s next
Identity Providers
Create secrets under Identity providers; attach and detach
Web Services
HTTPS URLs for HTTP apps in the sandbox
Network Policies
Allowlist and control sandbox egress
How a runtime works
Lifecycle, defaults, and what is inside a sandbox
Create Runtime
All create parameters
Access Runtime
SSH or web terminal