This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
EAS Simulator REST API
Edit page
Create, inspect, connect to, and stop EAS Simulator sessions from your own systems with the REST API.
EAS Simulator is a limited-access preview. It is not included with paid or free plans and is currently available only to select partners. Join the waitlist if you are interested in trying it.
The EAS Simulator REST API lets you manage remote device sessions from CI, an agent, or another HTTP client without running EAS CLI. All endpoints live under https://api.expo.dev. Requests and responses are JSON, and successful responses wrap the result in data.
Create a session, poll it until connection details are available, and stop it when you finish. The REST API manages the session lifecycle. Use the selected controller for device actions such as installing an app, pressing a button, or taking a screenshot.
Authentication
All endpoints require an Expo access token, sent as a bearer token in the Authorization header. The account that owns the project must have EAS Simulator access.
For production integrations, create a robot user on the account that owns the project and assign it the Developer role, the minimum role that can create and stop sessions. A personal access token also works for scripts.
Authorization: Bearer <EXPO_TOKEN> Content-Type: application/json
The examples below read the token from the EXPO_TOKEN environment variable. Keep this token in your CI secret store or server environment, not in client code.
Session responses can include controller credentials. Treat connection details as secrets: do not commit them, include them in logs, or expose them in a public response. Successful responses carry
Cache-Control: private, no-storeandPragma: no-cache. Do not cache session responses.
Create a session
POST /v2/device-run-sessions
Creates a session and queues the remote device. The request returns before the device and controller are ready.
Request body
Choose at most one application source: buildId, applicationArchiveUrl, or expoGo: true. Providing more than one returns 400. You can omit all three to start with a blank device.
UUID means universally unique identifier.
The application source options install and launch the app for agent-device, argent, and serve-sim sessions. For appium, install and launch the app through your Appium client.
The REST API uses serve-sim for the session type that EAS CLI calls web-preview-only. It is only available on iOS and does not support an idle timeout. Other session types provide a controller and include a web preview on supported iOS sessions.
Example
Replace appId and buildId with your EAS project ID and a compatible build ID:
Response
Returns 200 OK with the new session's metadata:
{ "data": { "id": "019d9d17-013a-7e05-89aa-4aa83ff68c32", "appId": "a415eac6-231a-4b38-b481-3255a59f13b8", "url": "https://expo.dev/accounts/acme/projects/example/simulator-sessions/019d9d17-013a-7e05-89aa-4aa83ff68c32", "jobRunId": "019d9d17-1a3f-7c10-bdee-5f2811a9d6ad", "name": "Checkout flow screenshots", "type": "agent-device", "packageVersion": null, "buildId": "f9609423-5072-4ea2-a0a5-c345eedf2c2a", "applicationArchiveUrl": null, "platform": "ios", "status": "new", "remoteConfig": null, "maxDurationMinutes": 30, "maxIdleTimeMinutes": 5, "startedAt": null, "finishedAt": null, "createdAt": "2026-08-28T10:00:00.000Z", "updatedAt": "2026-08-28T10:00:00.000Z" } }
Save data.id and set it as SESSION_ID for the remaining examples. url links to the session page on expo.dev. It is not the live browser preview URL.
buildId contains the supplied build ID. applicationArchiveUrl contains the supplied archive URL or the resolved Expo Go archive URL. It is null when using buildId. Optional values such as name, packageVersion, and maxIdleTimeMinutes are null when omitted.
The response's maxDurationMinutes matches the requested session duration. A request for 30 minutes returns 30.
remoteConfig is null while the session is starting. Poll the get endpoint for status and connection details together.
Get a session
GET /v2/device-run-sessions/:deviceRunSessionId
Returns 200 OK with the same session object as the create endpoint, including its current status, timestamps, and remoteConfig. Replace :deviceRunSessionId with the session ID. No separate connection request is needed.
Example
Response
An agent-device session that is ready returns connection details alongside its metadata:
{ "data": { "id": "019d9d17-013a-7e05-89aa-4aa83ff68c32", "appId": "a415eac6-231a-4b38-b481-3255a59f13b8", "url": "https://expo.dev/accounts/acme/projects/example/simulator-sessions/019d9d17-013a-7e05-89aa-4aa83ff68c32", "jobRunId": "019d9d17-1a3f-7c10-bdee-5f2811a9d6ad", "name": "Checkout flow screenshots", "type": "agent-device", "packageVersion": null, "buildId": "f9609423-5072-4ea2-a0a5-c345eedf2c2a", "applicationArchiveUrl": null, "platform": "ios", "status": "in-progress", "remoteConfig": { "agentDeviceRemoteSessionUrl": "https://controller.example.com", "agentDeviceRemoteSessionToken": "<session-token>", "webPreviewUrl": "https://preview.example.com" }, "maxDurationMinutes": 30, "maxIdleTimeMinutes": 5, "startedAt": "2026-08-28T10:01:00.000Z", "finishedAt": null, "createdAt": "2026-08-28T10:00:00.000Z", "updatedAt": "2026-08-28T10:01:00.000Z" } }
Session status
The REST API returns lowercase status values:
Poll this endpoint every five seconds until status is in-progress and remoteConfig is not null, then connect using that configuration. Set a timeout in your integration. If the status becomes stopped or errored, stop polling and inspect the session page at url.
Connection details
The fields in remoteConfig depend on the session type. Connection details are only returned while the session is in-progress. After it stops or errors, the session response returns remoteConfig: null even if the session previously had connection details.
For agent-device, use the URL and token as AGENT_DEVICE_DAEMON_BASE_URL and AGENT_DEVICE_DAEMON_AUTH_TOKEN. For Argent, use toolsUrl and toolsAuthToken as ARGENT_TOOLS_URL and ARGENT_AUTH_TOKEN. For Appium, configure your client with appiumUrl and capabilities. See Run and control an app for controller usage.
Open webPreviewUrl (or previewUrl for serve-sim) in a desktop browser to view supported iOS sessions. Do not open it on the remote device. Android sessions do not currently provide a browser preview.
Stop a session
POST /v2/device-run-sessions/:deviceRunSessionId/stop
Stops a session. This endpoint does not require a request body.
Example
Response
Returns 200 OK with the session object. An active session transitions to stopped, includes finishedAt, and returns remoteConfig: null. The operation is idempotent: if the session is already stopped or errored, it returns that session without changing its status or finish time. Connection details remain null.
Always stop the session when your work finishes, including on errors or polling timeouts. Returning from an HTTP request does not stop the remote device. Use a cleanup handler in your integration and set maxDurationMinutes to limit unattended usage.
Errors
Use the returned error message to identify which option or permission needs attention. For session startup failures, inspect the session page linked by url.
Next step
Choose a compatible build, connect a controller, and interact with the remote device.