Security.Run Docs

SECURITY.RUN / DOCUMENTATION

HTTP API reference

Base URL: https://www.security.run. Requests and responses use JSON. Authenticate private routes with Authorization: Bearer YOUR_SECURITY_RUN_CREDENTIAL. See Authentication before using the API.

Catalog and account

Method Path Result
GET /healthz Public service health.
GET /v1/images Public image catalog under images, with credit rates.
GET /v1/billing/config Public billing availability and trial settings.
GET /auth/me Authenticated owner identity.
GET /v1/billing/account Remaining, promotional, paid and spent credits; account limits.
GET /v1/billing/history Recent credit activity under entries; each entry has amount_credits, kind, and Unix at time.
GET /v1/billing/statements Stripe balance expressed in credits, plus invoices and hosted statement URLs.
Shell
curl --fail-with-body https://www.security.run/v1/billing/account \
  -H "Authorization: Bearer $SECURITY_RUN_API_KEY"

Read hourly_credits and egress_gib_credits from each image's pricing. Use the current catalog IDs rather than guessing image names. Older USD fields remain compatibility aliases; new clients should use credit fields.

Security desktop images have desktop: true and access: "rdp". Parrot, SIFT and REMnux also support SSH. Their sizes array contains Standard only; the gallery and SDKs use the same catalog.

Quote a session

POST /v1/sessions/quote accepts the same session input as launch. It returns rates, max_credits, egress_budget_credits, ttl_seconds, and the concurrency limit. These are informational upper limits. It does not create a session or spend credits, and launch does not require the full quoted amount.

Shell
curl --fail-with-body https://www.security.run/v1/sessions/quote \
  -H "Authorization: Bearer $SECURITY_RUN_API_KEY" \
  -H 'Content-Type: application/json' \
  --data '{"image":"ubuntu-24.04","ttl_seconds":1800,"egress_budget_credits":10}'

Create a session

POST /v1/sessions requires an Idempotency-Key header and returns 202 Accepted with a session object.

Input Type Constraints
image string, required Exact catalog ID, such as ubuntu-24.04.
ttl_seconds integer 300–14,400; trial accounts are limited to 1,800. The raw HTTP default is 3,600, so explicitly send 1,800 for trial sessions.
egress_budget_credits integer 10–500; default 50.
Idempotency-Key header string, required 1–128 characters; unique per logical launch and reused for identical retries.
Shell
curl --fail-with-body https://www.security.run/v1/sessions \
  -H "Authorization: Bearer $SECURITY_RUN_API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: case-482-linux' \
  --data '{"image":"ubuntu-24.04","ttl_seconds":1800,"egress_budget_credits":10}'

The response includes id, image, state, ip, browser_url, created_at, expires_at, cleanup_status, and billing information. IP can be null until ready. Native credentials are retrieved separately. Timestamps are Unix seconds.

Use the exact same idempotency key and body after an uncertain response. A changed request body under a used key conflicts. A key does not create another VM when the original session has ended; use a new key for a new session.

Read, connect and destroy

Method Path Result
GET /v1/sessions Owner-scoped sessions array and next_cursor.
GET /v1/sessions/{id} Current session without native credentials.
GET /v1/sessions/{id}/connection Ready session plus native connection details.
POST /v1/sessions/{id}/browser Short-lived, owner-authorized browser-gateway handoff URL. Normally handled by the web app.
DELETE /v1/sessions/{id} Request teardown; 202 does not mean cleanup is already complete.

For listing, send the returned next_cursor as the URL-encoded cursor query parameter until it is null. Both SDKs follow these pages automatically. A cursor belongs to its authenticated owner.

Poll a session with a delay of a few seconds while it starts. Once state is ready, retrieve /connection. It returns ip, port, protocol, browser_url, and a credentials object. Open the regular browser_url in the web app; it still requires the owner's sign-in.

For Linux security desktops, protocol is rdp, port is 3389, and ssh_port is 22. The same response contains both a desktop password and an SSH private_key, along with their shared username. Always use the returned username: SIFT uses sansforensics, REMnux uses remnux, and Parrot uses runner. Windows/FLARE credentials contain a password and have no SSH port.

Shell
curl --fail-with-body https://www.security.run/v1/sessions/ses_YOUR_SESSION_ID \
  -H "Authorization: Bearer $SECURITY_RUN_API_KEY" \
  -X DELETE

Poll until the terminal state and inspect cleanup_status. Repeat DELETE safely if the response was lost. There is no session extension, pause/resume, snapshot, in-place size-change, or remote command execution endpoint in this release.

Checkout

POST /v1/billing/checkout requires an Idempotency-Key and one of these JSON bodies:

JSON
{"kind":"trial","amount_usd":0}
JSON
{"kind":"topup","amount_usd":10}

Supported top-up amounts are 10, 25, 50 and 100 USD. These are purchase prices, not usage balances. The result contains an id and a Stripe-hosted url. Open that URL to complete card verification or payment; do not collect raw card details yourself.

GET /v1/billing/checkouts/{id} returns checkout fulfillment state. fulfilled means credits were granted; failed or rejected includes a reason. Any other state can still be pending. A successful browser redirect alone does not grant credits: verified Stripe webhook processing does.

Error responses

Errors normally include a human-readable detail. Billing errors also have a machine-readable code; request validation can return a structured detail array.

Status Typical meaning Action
400 Invalid amount or cursor Correct the request.
401 Missing, expired or invalid credential Sign in again or check the supplied credential.
402 Not enough credits for the compute minimum Add credits or activate an eligible trial.
403 Email confirmation, trial limit, or account hold Follow the reason in the response.
404 Session/image unavailable to this owner Check the ID, catalog and identity.
409 Not ready or conflicting request Wait for readiness, or fix idempotency-key reuse.
422 Invalid request fields Check names, types and limits.
429 Rate, concurrency or capacity limit Back off; finish an existing session when applicable.
503 Temporary service or billing unavailability Retry with backoff and preserve the launch key.

The SDKs retry transient network failures and HTTP 429/502/503/504 up to three attempts. They do not turn a timeout into cancellation. See Troubleshooting for recovery steps.

Size and inactivity options

POST /v1/sessions and /v1/sessions/quote accept size: "small" | "standard". Omit it for Small on basic Linux terminals or Standard on desktops. Unsupported combinations fail before allocation. GET /v1/images includes the default size, resource specifications, pricing, and a sizes array. Existing sessions keep their launch size and rate.

Session creation also accepts idle_timeout_seconds: 0 | 900 (default 0 for API clients). The browser sends 900. The idle timer begins when the guest becomes ready. An authenticated POST /v1/sessions/{id}/activity records activity using server time. PATCH /v1/sessions/{id}/idle with {"enabled": false} disables idle cleanup; true re-enables it and resets the 15-minute timer. These operations are owner-scoped and never extend expires_at. Metadata includes idle_timeout_seconds and, when enabled, idle_expires_at.

Need a hand? Contact support ↗