Cloud Examples
These examples use the Cloud REST API directly.
Setup
export SMOL_CLOUD_TOKEN="smk_your_key_here"
export SMOL_CLOUD_URL="https://api.smolmachines.com" The examples use jq to read JSON responses.
Create a machine and capture its ID
export MACHINE_ID="$(
curl --fail-with-body --silent -X POST \
"$SMOL_CLOUD_URL/v1/machines" \
-H "Authorization: Bearer $SMOL_CLOUD_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "examples",
"source": {"type": "image", "reference": "python:3.12-alpine"},
"resources": {"cpus": 1, "memoryMb": 512},
"network": {"mode": "open"}
}' |
jq -r '.id'
)"
printf '%s\n' "$MACHINE_ID" Run a command
An argv array avoids an extra shell parsing step:
curl --fail-with-body -X POST \
"$SMOL_CLOUD_URL/v1/machines/$MACHINE_ID/exec" \
-H "Authorization: Bearer $SMOL_CLOUD_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"command": ["python3", "-c", "print(sum(range(100)))"],
"timeoutSeconds": 30
}' Use a string when shell features such as pipes or redirection are required:
curl --fail-with-body -X POST \
"$SMOL_CLOUD_URL/v1/machines/$MACHINE_ID/exec" \
-H "Authorization: Bearer $SMOL_CLOUD_TOKEN" \
-H "Content-Type: application/json" \
-d '{"command":"printf \"%s\\n\" alpha beta | sort -r"}' Pass environment and stdin
curl --fail-with-body -X POST \
"$SMOL_CLOUD_URL/v1/machines/$MACHINE_ID/exec" \
-H "Authorization: Bearer $SMOL_CLOUD_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"command": ["python3", "-c", "import os,sys; print(os.environ[\"LABEL\"], len(sys.stdin.read()))"],
"env": {"LABEL": "payload-bytes"},
"stdin": "hello\n"
}' Values in env are visible to code inside the guest. Do not send a secret unless the workload should be able to read it.
Start a background service
Create a machine with a published port:
export WEB_MACHINE_ID="$(
curl --fail-with-body --silent -X POST \
"$SMOL_CLOUD_URL/v1/machines" \
-H "Authorization: Bearer $SMOL_CLOUD_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "example-web",
"source": {"type": "image", "reference": "python:3.12-alpine"},
"resources": {"cpus": 1, "memoryMb": 512},
"network": {"mode": "open"},
"ports": [{"port": 8000}],
"public": false
}' |
jq -r '.id'
)" Start a detached HTTP server:
curl --fail-with-body -X POST \
"$SMOL_CLOUD_URL/v1/machines/$WEB_MACHINE_ID/exec" \
-H "Authorization: Bearer $SMOL_CLOUD_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"command": ["python3", "-m", "http.server", "8000", "--directory", "/workspace"],
"background": true
}' Use background for detached execution when the endpoint supports it.
Wait for readiness:
ready=false
for _ in $(seq 1 60); do
record=$(curl --fail --silent \
"$SMOL_CLOUD_URL/v1/machines/$WEB_MACHINE_ID" \
-H "Authorization: Bearer $SMOL_CLOUD_TOKEN") || {
sleep 1
continue
}
if jq -e '.ready == true' >/dev/null <<<"$record"; then
ready=true
break
fi
if jq -e '(has("ready") | not) and .state == "started"' \
>/dev/null <<<"$record" &&
curl --fail --silent \
"$SMOL_CLOUD_URL/v1/machines/$WEB_MACHINE_ID/connect/8000/" \
-H "Authorization: Bearer $SMOL_CLOUD_TOKEN" >/dev/null; then
ready=true
break
fi
sleep 1
done
[ "$ready" = true ] || {
echo "machine did not become ready within 60 seconds" >&2
exit 1
} For older records without ready, the loop waits for started and probes the application through the authenticated connect route.
Connect through the authenticated bridge:
curl --fail \
"$SMOL_CLOUD_URL/v1/machines/$WEB_MACHINE_ID/connect/8000/" \
-H "Authorization: Bearer $SMOL_CLOUD_TOKEN" Confirm published-port fields and the connect route in the API Explorer before using this example in production.
Use a restricted egress policy
curl --fail-with-body -X POST \
"$SMOL_CLOUD_URL/v1/machines" \
-H "Authorization: Bearer $SMOL_CLOUD_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "restricted",
"source": {"type": "image", "reference": "alpine"},
"network": {
"mode": "allowCidrs",
"hosts": ["example.com"],
"cidrs": []
}
}' The image pull runs inside the guest. When a hostname allow-list is in force, the image’s own registry is folded into the enforced egress policy automatically, so you do not need to list it. Add registry or package hosts only when software running inside the guest must reach them at runtime — or when a registry serves its blobs from a different host than the one in the image reference, which the automatic fold does not cover.
List and inspect machines
List every machine on the account:
curl --fail --silent "$SMOL_CLOUD_URL/v1/machines" \
-H "Authorization: Bearer $SMOL_CLOUD_TOKEN" |
jq '.[] | {id, name, state, ready}' Read one machine in full:
curl --fail --silent \
"$SMOL_CLOUD_URL/v1/machines/$MACHINE_ID" \
-H "Authorization: Bearer $SMOL_CLOUD_TOKEN" |
jq Stop and clean up
Stop a machine while keeping its data:
curl --fail-with-body -X POST \
"$SMOL_CLOUD_URL/v1/machines/$MACHINE_ID/stop" \
-H "Authorization: Bearer $SMOL_CLOUD_TOKEN" Delete example machines when finished:
curl --fail-with-body -X DELETE \
"$SMOL_CLOUD_URL/v1/machines/$MACHINE_ID" \
-H "Authorization: Bearer $SMOL_CLOUD_TOKEN"
curl --fail-with-body -X DELETE \
"$SMOL_CLOUD_URL/v1/machines/$WEB_MACHINE_ID" \
-H "Authorization: Bearer $SMOL_CLOUD_TOKEN"