Authentication
All Runra Sandbox API requests require authentication using a Bearer token in the Authorization header. This page covers how to obtain, configure, and secure your API keys.
Obtaining an API Key
Section titled “Obtaining an API Key”Via the Dashboard
Section titled “Via the Dashboard”- Log in to the Runra Dashboard.
- Navigate to Settings → API Keys.
- Click Create API Key.
- Give your key a descriptive name (e.g.,
production-ci,local-dev). - Select the appropriate scopes (see Scopes & Permissions).
- Copy the generated key immediately — it will not be shown again.
Via the CLI
Section titled “Via the CLI”runra auth loginrunra auth create-key --name "production-ci" --scope "full"Key Format
Section titled “Key Format”API keys are opaque tokens prefixed with rra_:
rra_live_x7k2m9p4q1w3v5b8n6c0d2a4fNever commit API keys to source control. Use environment variables:
export RUNRA_API_KEY="rra_live_x7k2m9p4q1w3v5b8n6c0d2a4f"Authenticating Requests
Section titled “Authenticating Requests”Include the key in the Authorization header on every request:
curl https://api.box.runra.dev/v1/sandboxes \ -H "Authorization: Bearer $RUNRA_API_KEY"TypeScript SDK
Section titled “TypeScript SDK”The SDK reads RUNRA_API_KEY from the environment automatically:
import { Runra } from "@runra/sandbox";
const client = new Runra({ apiKey: process.env.RUNRA_API_KEY, // or auto-reads from env});
// Or pass explicitlyconst client = new Runra({ apiKey: "rra_live_x7k2m9p4q1w3v5b8n6c0d2a4f",});Python SDK
Section titled “Python SDK”from runra import Runra
client = Runra(api_key="rra_live_x7k2m9p4q1w3v5b8n6c0d2a4f")Scopes and Permissions
Section titled “Scopes and Permissions”API keys can be scoped to limit what operations they can perform:
| Scope | Description |
|---|---|
sandbox:create | Create new sandboxes |
sandbox:read | List and get sandbox details |
sandbox:delete | Terminate sandboxes |
sandbox:pause | Pause and resume sandboxes |
sandbox:execute | Run code inside sandboxes |
sandbox:files | Read and write files |
sandbox:ports | Expose and close ports |
sandbox:* | Full sandbox management |
billing:read | View usage and billing |
billing:manage | Update billing details |
webhooks:manage | Create and manage webhooks |
Predefined profiles:
| Profile | Includes |
|---|---|
read-only | sandbox:read, billing:read |
sandbox-user | sandbox:create, sandbox:read, sandbox:delete, sandbox:pause, sandbox:execute, sandbox:files, sandbox:ports |
admin | sandbox:*, billing:*, webhooks:manage |
Create a scoped key:
runra auth create-key \ --name "ci-worker" \ --scope "sandbox:create,sandbox:execute,sandbox:delete"Key Rotation
Section titled “Key Rotation”Rotate API keys regularly to limit exposure from leaked credentials. Runra supports overlapping keys during rotation:
Rotation Steps
Section titled “Rotation Steps”- Create a new key with the same scopes:
runra auth create-key --name "production-v2" --scope "admin"# → rra_live_newkey...-
Deploy the new key to all services. Both keys are valid simultaneously.
-
Revoke the old key after confirming the new key works:
runra auth revoke-key --key-id "key_abc123def456"Via the Dashboard
Section titled “Via the Dashboard”- Go to Settings → API Keys.
- Click Rotate on the key you want to replace.
- A new key is created and the old key remains valid for 7 days.
- After 7 days, the old key is automatically revoked.
Automated Rotation
Section titled “Automated Rotation”For production systems, use the key listing endpoint to check key ages:
curl https://api.box.runra.dev/v1/keys \ -H "Authorization: Bearer $RUNRA_API_KEY"{ "data": [ { "id": "key_abc123def456", "name": "production-v1", "prefix": "rra_live_x7", "createdAt": "2025-12-15T10:00:00Z", "lastUsedAt": "2026-06-15T09:55:00Z", "scopes": ["sandbox:*"], "isActive": true } ]}Security Best Practices
Section titled “Security Best Practices”Never expose keys in client-side code
Section titled “Never expose keys in client-side code”API keys grant access to create and manage sandboxes. Only use them in server-side or edge environments:
// ✅ Server-side (Next.js API route, Express, worker)const runra = new Runra({ apiKey: process.env.RUNRA_API_KEY });
// ❌ Client-side (browser, mobile app)// const runra = new Runra({ apiKey: "rra_live_..." });If you need browser access, proxy requests through your backend.
Use environment variables
Section titled “Use environment variables”# .env (never commit this file)RUNRA_API_KEY=rra_live_x7k2m9p4q1w3v5b8n6c0d2a4f// Load from envconst apiKey = process.env.RUNRA_API_KEY;if (!apiKey) { throw new Error("RUNRA_API_KEY is required");}Scope keys to minimum permissions
Section titled “Scope keys to minimum permissions”Give each integration only the scopes it actually needs:
# CI pipeline only needs to create, execute, and clean uprunra auth create-key \ --name "ci-pipeline" \ --scope "sandbox:create,sandbox:execute,sandbox:delete"Monitor key usage
Section titled “Monitor key usage”Check the API keys dashboard for unusual activity. Keys show lastUsedAt timestamps and request counts. Set up alerts for:
- Keys not used in 30+ days (revoke them)
- Unexpected scope usage
- Sudden spikes in request volume
Revoke compromised keys immediately
Section titled “Revoke compromised keys immediately”# Via CLIrunra auth revoke-key --key-id "key_abc123def456"
# Via APIcurl -X DELETE https://api.box.runra.dev/v1/keys/key_abc123def456 \ -H "Authorization: Bearer $RUNRA_API_KEY"Authentication Errors
Section titled “Authentication Errors”| Status | Code | Meaning |
|---|---|---|
401 | UNAUTHORIZED | Missing Authorization header or invalid key |
403 | FORBIDDEN | Valid key but insufficient scope for the operation |
401 | KEY_EXPIRED | Key has been revoked or expired |
{ "error": { "code": "UNAUTHORIZED", "message": "Invalid API key", "requestId": "req_a1b2c3d4" }}Next Steps
Section titled “Next Steps”- API Overview — base URL, rate limits, error format
- Sandboxes API — sandbox management endpoints
- Execution API — code execution endpoints