Skip to main content
@run-cloud/sdk is the API-key client for iOS simulator sessions, Android emulator sessions, microVM sandboxes, snapshots, account state, and reusable app assets. It also packages and submits remote Xcode builds. It requires Node.js 20 or newer. See the latest SDK reference for the complete class, method, option, and response-type index.

Install

Authenticate

Create an API key in the run.cloud dashboard, then expose it to the process that runs your application:
The client reads RUN_CLOUD_API_KEY automatically. You can also pass the key directly when your application loads secrets another way:
Set RUN_CLOUD_API_URL or pass apiUrl to use a non-default API host. Do not put API keys in source code, browser bundles, logs, or committed environment files.

Build an Xcode project

The returned ID remains usable after the submitting process exits. Use cloud.xcode.get, list, events, logs, cancel, and downloadArtifact to reconnect to the build. See Build with Xcode for signing, source filters, React Native, XcodeGen, App Store upload, and lifecycle details. For JavaScript-only Expo or React Native changes, reuse the compatible native shell and launch the resulting immutable Asset with a stable retry key:
Use cloud.capabilities.create when another process needs temporary access to only the selected Asset, build, or launch idempotency key. Capability secrets expire in at most one hour and can be revoked sooner.

Run the complete example

The runnable example checks account access, creates iOS and Android sessions, opens a URL on each platform, and releases both sessions even when the run is interrupted or fails:
See newly-app/run-cloud-examples/sdk-ios-android for platform, codec, duration, and JSON-output options.

Create and release sessions

Use the platform client when the platform is known. Always release metered sessions in finally so a failed test does not leave them running:
cloud.ios and cloud.android both provide: The iOS client additionally provides:
  • uploadVideo(id, video, options), which accepts an MP4 or QuickTime Blob and imports it into Photos. The uploaded file remains in cloud.assets for reuse or deletion. This is distinct from uploadCameraVideo, which presents frames to the app camera.
Camera injection, microphone injection, screenshots, screen recordings, accessibility trees, and simulator interactions are available on both platform clients. See Read the Accessibility Tree for its schema and test patterns. SimulatorOpenUrlResult contains ok, platform, sessionId, device, leaseId, and the exact input url. Percent encoding is not normalized. See Open URLs and Deep Links for complete encoded HTTPS and custom-scheme examples, the direct REST request, platform behavior, and errors.

Record the display

Start and stop capture independently of the viewer stream, then download the ready MP4 through the authenticated API:
Use listRecordings and getRecording to inspect lifecycle state, failures, events, retention, and retrieval metadata. The same methods are available on cloud.android and cloud.simulators. See Record a Simulator for retry, release, retention, CLI, and REST details.

Control the session

Coordinates use the current display with { x: 0, y: 0 } at the top-left and { x: 1, y: 1 } at the bottom-right. Each call resolves with a correlated, typed acknowledgement:
Options accept requestId, timeoutMs, and signal. Aborting stops the caller from waiting but does not release the session. Digital Crown input is unavailable on current mobile sessions. Render-debug operations are iOS-only. Unsupported calls fail with a typed API error. See Control a Simulator for every method, gesture payloads, keys, buttons, result types, and platform behavior.

Inject camera and microphone media

Both platform clients upload a user-owned media asset and inject it into the active app. Pass the target bundle/package ID so the acknowledgement identifies the intended native receiver:
Use cloud.ios in the same calls for an iOS Simulator. Camera input accepts MP4 and QuickTime. Microphone input accepts AAC, M4A, MP3, MP4-audio, and WAV. Delete the returned asset through cloud.assets.delete() when it is no longer needed. For an iOS Photos import instead, use cloud.ios.uploadVideo().

Use the generic simulator client

Use cloud.simulators when the platform is selected at runtime. Pass the session platform back to methods that operate on an existing session:
cloud.simulators.list() returns every platform unless platform is supplied. Other generic simulator lifecycle and interaction methods default to iOS when platform is omitted. cloud.simulators.screenshot(id, { platform }) and cloud.simulators.accessibilityTree(id, { platform }) work on both platforms.

Run the screenshot examples

The maintained iOS and Android examples build a small native app, install it in a session, save screenshots/run-cloud-proof.png, validate the image, and release the session:
Pass --open to open the signed viewer during the run or --app <path> to use a prebuilt artifact. Building iOS requires macOS and Xcode. Building Android requires JDK 17 or newer and Android SDK 35 or newer. The complete source is in the iOS example and Android example.

Check account state

Use account() before starting a larger test matrix when you want to surface access or organization information early:

Upload and reuse assets

Upload an artifact once, then reference its id from one or more sessions:
cloud.assets provides upload, list, and delete. Artifact contents must match the target platform: iOS needs a simulator-compatible build, while Android needs an Android-compatible artifact such as an APK.

Handle API errors

Non-successful responses throw RunCloudError with the HTTP status, structured error fields, and interaction correlation metadata when available:
isSimulatorCapacityError(error) matches only the typed, retry-safe simulator_capacity_unavailable 503 response. Use a bounded retry for that case; authentication, validation, and other service errors do not match it. URL-opening failures use stable invalid_url, active_session_not_found, lease scope, ended session, platform handler, timeout, and transport codes described in Open URLs and Deep Links. For these failures, action is the SDK operation name "open-url", while suggestedAction is the API’s human-readable remediation.