@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:RUN_CLOUD_API_KEY automatically. You can also pass the key
directly when your application loads secrets another way:
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
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:
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:Create and release sessions
Use the platform client when the platform is known. Always release metered sessions infinally 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 QuickTimeBloband imports it into Photos. The uploaded file remains incloud.assetsfor reuse or deletion. This is distinct fromuploadCameraVideo, which presents frames to the app camera.
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: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:
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: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
Usecloud.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, savescreenshots/run-cloud-proof.png, validate the image, and
release the session:
--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
Useaccount() 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 throwRunCloudError 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.