Create. Execute.
Stay in control.
Create your Sandbox account with your email address, or sign in if you already have one. No existing AGNT account or app subscription is required. Headless agents can register and fund themselves over HTTP.
Open your account →Headless signup (agents)
No email, no browser. The secret is your identity. Store it securely; it is shown only once.
# Headless signup. Store the secret: it is shown only once.
curl -X POST https://sandbox.agnt.gg/sandbox/v1/agents \
-H 'Content-Type: application/json' \
-d '{"name":"my-agent"}'
# 201 { "agentId": "agt_...", "secret": "sandbox_...", "balance": 0,
# "fund": { "claimUrl": "https://sandbox.agnt.gg/claim/agt_..." } }
# Share claimUrl with the person funding the agent, or pay with x402.
# Fund the account and activate hosting before creating a sandbox.Funding does not grant the person paying access to the agent’s files or commands. Buy hosting after funding, then create a sandbox. Use GET /sandbox/v1/usage to inspect the account’s allowance.
Agents pay for themselves with x402
Request a funding order, sign the returned authorization in USDC on Base, and the payment credits this product’s prepaid balance. Settlement uses the Coinbase facilitator and is recorded as a Stripe payment. Your wallet needs USDC on Base; the facilitator pays gas.
The client (JavaScript)
// npm i @x402/core @x402/evm viem
import { privateKeyToAccount } from 'viem/accounts';
import { x402Client } from '@x402/core/client';
import { registerExactEvmScheme } from '@x402/evm/exact/client';
const base = 'https://sandbox.agnt.gg/sandbox/v1';
const auth = { Authorization: 'Bearer ' + process.env.SANDBOX_SECRET,
'Content-Type': 'application/json' };
const client = new x402Client().setSpendControls({ maxAmountPerPayment: '$10' });
registerExactEvmScheme(client, {
signer: privateKeyToAccount(process.env.WALLET_PRIVATE_KEY),
networks: ['eip155:8453']
});
const created = await fetch(base + '/funding/x402', {
method: 'POST', headers: auth, body: JSON.stringify({ amountCents: 1000 })
});
if (created.status !== 402) throw new Error('Funding order rejected');
const order = await created.json();
const payload = await client.createPaymentPayload(order.requirements);
const paid = await fetch(base + '/funding/x402/' + order.orderId, {
method: 'POST', headers: { ...auth,
'PAYMENT-SIGNATURE': Buffer.from(JSON.stringify(payload)).toString('base64') },
body: '{}'
});
if (!paid.ok) throw new Error('Payment rejected: ' + await paid.text());
const result = await paid.json();
if (result.state !== 'credited') throw new Error('Poll order until credited');
await fetch(base + '/hosting/purchase', {
method: 'POST', headers: { ...auth, 'Idempotency-Key': order.orderId },
body: JSON.stringify({ plan: 'starter' })
});
// Now create a sandbox. Never send the wallet private key to the service.Payment limits
- Top-ups: $10, $25, or $50. Set an explicit client spending cap at least as large as the selected payment.
- Orders expire after 10 minutes. Poll the same order on uncertain responses; do not submit a new payment blindly.
- Protocol x402 v2, network
eip155:8453, asset USDC. Never send a wallet private key to the API.
Create your Sandbox account
- Enter your email on the account page, then verify the six-digit code.
- Add prepaid credit with Stripe Checkout ($10 minimum), or use an eligible included AGNT plan.
- Activate hosting from the prepaid balance and create an environment.
- Run a command, export the result, and destroy the environment when finished.
The account page also accepts a Sandbox API secret. Human card checkout requires an email-authenticated account. Agents can use x402 or share their funding link.
Create and execute
All API calls except signup and public policy require Authorization: Bearer <secret>. Creation and execution requests require Idempotency-Key. Reuse the same key on retries.
curl -X POST https://sandbox.agnt.gg/sandbox/v1/sandboxes \
-H 'Authorization: Bearer sandbox_...' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: create-your-unique-id' \
-d '{"size":"small","lifetimeSeconds":600,"network":"offline"}'
# 202 { "id": "...", "state": "queued", ... }
# Poll GET /sandbox/v1/sandboxes/ID until state is "ready".
# Queued/provisioning time is not billed; ready time is billed even while idle.curl -X POST https://sandbox.agnt.gg/sandbox/v1/sandboxes/ID/executions \
-H 'Authorization: Bearer sandbox_...' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: execute-your-unique-id' \
-d '{"command":"python3 --version && node --version","timeoutSeconds":60}'
# 202 { "id": "...", "state": "queued" }
# Poll GET /sandbox/v1/executions/EXECUTION_ID for exit_code and output.
# output is a JSON-encoded object. Parse it to read stdout and truncation flags.
# A command timeout terminates the sandbox, not just the command.Lifecycle: queued → provisioning → ready → stopping → destroyed. Failed provisioning is not billed. A lost worker retains reservations until teardown is confirmed. Commands are not replayed automatically after a worker failure.
Execution results include state, exit_code, and output. Parse the JSON-encoded output object to read its output, truncated, and timedOut fields.
Files and retained artifacts
# Upload a new file (8 MB maximum; existing files are never overwritten).
curl -X POST https://sandbox.agnt.gg/sandbox/v1/sandboxes/ID/uploads \
-H 'Authorization: Bearer sandbox_...' \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: upload-your-unique-id' \
-d '{"path":"input.txt","base64":"aGVsbG8="}'
# Export: POST /sandbox/v1/sandboxes/ID/exports {"path":"result.txt"}
# Both return { id, state: "queued" }; poll GET /sandbox/v1/transfers/ID.
# A completed export returns result.artifactId.
# GET /sandbox/v1/artifacts/ARTIFACT_ID downloads its bytes (authenticated).Paths are relative to /workspace. Parent directories must exist. Uploads never overwrite an existing file. Traversal, symlinks, hardlinks, and special files are rejected. Poll transfers until completed or failed before using their results.
Exported artifacts remain available for 1, 7, or 30 days, within the plan’s storage cap. Downloads require authentication and consume the pooled monthly transfer allowance (1, 5, or 15 GB). Downloaded active content remains untrusted.
Receivers and signed delivery
curl -X POST https://sandbox.agnt.gg/sandbox/v1/webhooks \
-H 'Authorization: Bearer sandbox_...' \
-H 'Content-Type: application/json' \
-d '{"url":"https://your-agent.example/events"}'
# 201 { "id": "...", "secret": "..." } — save the signing secret.
# HMAC-SHA256(secret, timestamp + "." + rawBody)
# Headers: X-AGNT-Event-ID, X-AGNT-Timestamp, X-AGNT-Signature: v1=<hex>
# Verify signature and timestamp freshness; deduplicate on event ID.
# GET /sandbox/v1/notifications and /webhook-deliveries show delivery history.Lifecycle messages contain {id, type, objectId, state, createdAt}. Examples include sandbox.ready, sandbox.destroyed, execution.completed, and artifact.retained.
Verify HMAC-SHA256 over the timestamp, a period, and the exact raw body. Reject stale timestamps and deduplicate on event ID. Receivers must use public HTTPS on port 443; private networks and redirects are rejected. Failed deliveries retry with backoff. Repeated failures pause a receiver; remove and register it again after correcting the destination.
Keys, cancellation, and teardown
POST /sandbox/v1/keys
{"scopes":["sandbox:read","sandbox:execute"],"sandboxId":"SANDBOX_ID"}
GET /sandbox/v1/keys
DELETE /sandbox/v1/keys/KEY_ID
# Account-level operations require sandbox:manage.
# Resource-bound keys cannot manage funding or create more environments.curl -X DELETE https://sandbox.agnt.gg/sandbox/v1/sandboxes/ID \ -H 'Authorization: Bearer sandbox_...' # Poll GET /sandbox/v1/sandboxes/ID until state is "destroyed". # Guest execution stops, scratch storage is removed, unused reservations release. # Explicitly exported artifacts survive until their retention window ends.
Revoked keys stop authenticating immediately. Destroying a session is irreversible. Its temporary filesystem disappears; only exported artifacts remain until expiry.
Hosting and limits
- Small: 1 shared-host vCPU, 1 GB RAM, 1 unit per started minute. Medium: 2/2, 2 units. Large: 4/4, 4 units; Pro and Business only.
- Maximum lifetime: 30 minutes / 2 hours / 4 hours. Idle ready time counts. A lease cannot cross the current hosting or UTC allowance boundary.
- Temporary disk is memory-backed. Logical 2/4/8 GB scratch limits do not add memory to the VM.
- 8 MB per transfer. Up to 128 execution records and 10 MB retained output per sandbox. Execution output expires after 30 days.
- Offline networking only. No inherited secrets, host mounts, arbitrary images, convenience jobs endpoint, or public listening ports.
GET /sandbox/v1/usage
GET /sandbox/v1/plans
GET /sandbox/v1/capabilities
POST /sandbox/v1/hosting/purchase {"plan":"starter"} + Idempotency-Key
PUT /sandbox/v1/hosting/preferences {"autoRenew":false,"allowOverage":false}Hosting is prepaid from credit. Included units reset on day 1 UTC with no rollover; cash balance persists. Extra units cost $2 per 1,000 only after opting in. Inspect capabilities before relying on a feature. Shared capacity can queue work; plan concurrency is not a reserved VM guarantee.
Standalone Sandbox plans
| Plan | Monthly hosting | Concurrent limit | Runtime units per month | Maximum lifetime | Artifacts |
|---|---|---|---|---|---|
| Starter | $5 | 1 | 1,000 | 30 minutes | 250 MB · 1 day |
| Pro | $15 | 3 | 5,000 | 2 hours | 1 GB · 7 days |
| Business | $39 | 6 | 20,000 | 4 hours | 3 GB · 30 days |
Per account, shared across sandboxes. One unit is one started Small sandbox-minute. Medium uses 2 units/minute; Large uses 4. Monthly units reset on day 1 UTC. Hosting is prepaid from credit; renewal and overage are optional. Concurrency is a ceiling, not reserved capacity. The current worker runs one VM at a time; additional requests queue for up to 120 seconds.
Already subscribe to AGNT?
Paid AGNT includes Sandbox by plan: Personal includes Starter (1,000 units/month); Always-On includes Pro (5,000 units/month); Business and Enterprise include Business (20,000 units/month). Limits are pooled per account. Purchased credit and current-month usage are preserved; higher active paid allowances remain available.