Sandboxes

Isolate test data from production — every resource is partitioned by sandbox so you can develop, test, and demo without affecting real users.

Overview

Sandboxes provide isolated data environments within your app. Every resource in the platform — users, teams, threads, agents, configs, integrations, and more — is partitioned by sandbox. Requests authenticated with a sandbox key only see and create data in that sandbox, completely isolated from production and from other sandboxes.

Production is sandbox_id = null. A sandbox is sandbox_id = <id>. The platform enforces this at the query level automatically — you never need to filter by sandbox manually.

Every new app starts with a default sandbox named "Test" and an initial publishable key, ready to use immediately.


Creating sandboxes

Create additional sandboxes through the SDK, CLI, or developer portal:

const sandbox = await client.sandboxes.create(appId, {
  name: "Staging",
  slug: "staging",
});

console.log("Sandbox:", sandbox.id);   // dsb_abc123
console.log("Slug:", sandbox.slug);    // "staging"

Slugs must be lowercase alphanumeric with hyphens, 2-100 characters, and unique per app. They cannot start or end with a hyphen.

# CLI
archastro create sandbox -n "Staging" -s staging

Sandbox API keys

Each sandbox has its own API keys, separate from your production app keys. Two key types are available:

Type Prefix Use case
Publishable pk_dsb_... Client-side code, safe to expose
Secret sk_dsb_... Server-side only, full access

Creating keys

// Create a publishable key (retrievable anytime)
const { full_key } = await client.sandboxes.createKey(appId, sandbox.id, "publishable");
console.log(full_key);  // pk_dsb_7xK9mQ2v_a8Yb3Zc5Wd2Qf9Gh

// Create a secret key (shown only once, then hashed)
const { full_key: secretKey } = await client.sandboxes.createKey(appId, sandbox.id, "secret");
console.log(secretKey);  // sk_dsb_7xK9mQ2v_j4Km8Np2Rt6Vx0Yw — save this immediately
# CLI
archastro create sandboxkey --sandbox dsb_abc123 -t publishable
archastro create sandboxkey --sandbox dsb_abc123 -t secret

Secret keys are hashed with bcrypt on creation. The full key is returned exactly once — if you lose it, revoke and create a new one.

Revoking keys

await client.sandboxes.revokeKey(appId, sandbox.id, keyId);
archastro revoke sandboxkey dsk_abc123 --sandbox dsb_abc123

Key properties

Field Type Description
id string Key ID (dsk_ prefix)
type enum publishable or secret
key_value string Full key (publishable only)
key_hint string Last 4 characters (always available)
status enum active or revoked
last_used_at datetime Updated on each authenticated request
expires_at datetime Optional expiry

How sandbox scoping works

When a request arrives with a sandbox API key (or a sandbox-scoped JWT), the platform:

  1. Identifies the sandbox from the key prefix
  2. Resolves the sandbox context from that key
  3. Scopes read operations to that sandbox automatically
  4. Tags new records to the same sandbox automatically

This means your code doesn't change at all between production and sandbox — just use a different API key.

Production key (pk_dap_...)  →  production workspace
Sandbox key (pk_dsb_...)     →  selected sandbox workspace

Sandbox scoping applies across all major runtime and control-plane resources, including users, teams, threads, messages, agents, configs, integrations, automations, files, and secrets.


Sandbox emails

Emails sent within a sandbox are captured instead of delivered. This lets you test email flows (registration, notifications, magic links) without sending real emails.

Viewing captured emails

// List all captured emails
const emails = await client.sandboxEmails.list(appId, sandbox.id);

// Get a specific email
const email = await client.sandboxEmails.get(appId, sandbox.id, emailId);
console.log(email.subject);
console.log(email.html_body);
# CLI
archastro list sandboxmails --sandbox dsb_abc123
archastro describe sandboxmail sem_abc123 --sandbox dsb_abc123

Email properties

Field Type Description
id string Email ID (sem_ prefix)
from_name string Sender name
from_address string Sender email address
to array Recipients [{name, address}]
cc, bcc array CC/BCC recipients
subject string Email subject line
text_body string Plain text content
html_body string HTML content
headers object Email headers

Cleaning up

// Delete one email
await client.sandboxEmails.delete(appId, sandbox.id, emailId);

// Delete all emails in a sandbox
const { deleted_count } = await client.sandboxEmails.deleteAll(appId, sandbox.id);
archastro delete sandboxmail sem_abc123 --sandbox dsb_abc123
archastro delete sandboxmails --sandbox dsb_abc123 --all

Using sandboxes with the CLI

The CLI can be scoped to a sandbox so all commands operate on sandbox data:

# Activate a sandbox (opens browser to re-authenticate with sandbox scope)
archastro activate sandbox

# List sandboxes — active sandbox is marked with *
archastro list sandboxes

When a sandbox is active, the CLI token includes the sandbox_id claim. All subsequent commands (creating users, agents, threads, etc.) will operate within that sandbox.


Developer portal

The portal at developers.archastro.ai provides a visual interface for sandbox management under App → Sandboxes:

  • Create and manage sandboxes
  • Generate publishable and secret keys (secret keys shown once in a dismissable banner)
  • View key status, hints, and last-used timestamps
  • Revoke keys with confirmation

API reference

Sandbox management

Operation Endpoint Description
List GET /apps/:app_id/sandboxes List all sandboxes with keys
Create POST /apps/:app_id/sandboxes Create a sandbox (auto-generates publishable key)
Show GET /apps/:app_id/sandboxes/:id Get sandbox details with keys
Create key POST /apps/:app_id/sandboxes/:id/keys Create a publishable or secret key
Revoke key POST /apps/:app_id/sandboxes/:id/keys/:key_id/revoke Revoke a key

Sandbox emails

Operation Endpoint Description
List GET /apps/:app_id/sandboxes/:id/emails List captured emails (newest first)
Show GET /apps/:app_id/sandboxes/:id/emails/:email_id Get email details
Delete DELETE /apps/:app_id/sandboxes/:id/emails/:email_id Delete one email
Delete all DELETE /apps/:app_id/sandboxes/:id/emails Delete all emails

Design patterns

Integration testing

Use a sandbox to run automated tests against the full platform API without affecting production:

  1. Create a sandbox (or use the default "Test" sandbox)
  2. Use the sandbox publishable key in your test suite
  3. Create users, agents, and threads — all isolated to the sandbox
  4. Verify email flows by checking captured sandbox emails
  5. Clean up by deleting sandbox emails between test runs

Demo environments

Create a named sandbox (e.g., demo) with pre-seeded data for customer demos. Each demo sandbox is isolated, so you can reset it independently without touching production or other sandboxes.

Staging pipeline

Use sandboxes as lightweight staging environments:

  1. test sandbox — automated test suite
  2. staging sandbox — manual QA and review
  3. Production — null sandbox (default app keys)

All three share the same app configuration (configs, workflows, agent definitions) but have completely separate user data, threads, and state.