This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
EAS 模拟器 REST API
通过 REST API,在你自己的系统上创建、查看、连接和停止 EAS 模拟器会话。
重要 EAS 模拟器是限量预览版本。 它不包含在付费或免费计划中,目前仅对精选合作伙伴开放。如果你有兴趣试用,请 加入等候名单。
EAS 模拟器的 REST API 让你可以从 CI、代理或其他 HTTP 客户端管理远程设备会话,而无需运行 EAS CLI。所有端点都位于 https://api.expo.dev 下。请求和响应都是 JSON,成功的响应会把结果包在 data 中。
🌐 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.
创建一个会话,轮询它直到连接详情可用,完成后停止它。REST API 会管理会话的生命周期。使用选定的控制器执行设备操作,比如安装应用、按按钮或截图。
🌐 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
所有端点都需要一个 Expo 访问令牌,作为承载令牌发送在 Authorization 头中。拥有该项目的账户必须有 EAS 模拟器访问权限。
🌐 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
下面的例子会从 EXPO_TOKEN 环境变量读取令牌。请把这个令牌保存在你的 CI 密钥存储或服务器环境中,不要放在客户端代码里。
🌐 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.
警告 会话响应可能包含控制器凭据。将连接详情视为密钥:不要提交它们,不要将它们记录在日志中,也不要在公共响应中泄露。成功的响应会包含
Cache-Control: private, no-store和Pragma: no-cache。不要缓存会话响应。
创建一个会话
🌐 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
最多选择一个应用来源: buildId、applicationArchiveUrl 或 expoGo: true。如果提供多个,会返回 400。你也可以全部省略,从而用空白设备开始。
UUID 意思是全局唯一标识符。
🌐 UUID means universally unique identifier.
应用源选项可以为 agent-device、argent 和 web-preview-only 会话安装并启动应用。对于 appium,请通过你的 Appium 客户端安装并启动应用。
🌐 The application source options install and launch the app for agent-device, argent, and web-preview-only sessions. For appium, install and launch the app through your Appium client.
web-preview-only 会话提供网页预览,但没有控制器。它不支持空闲超时。其他会话类型提供控制器并包括网页预览。在 serve-sim 被移除之前创建的会话仍然会返回 "type": "serve-sim"。
🌐 A web-preview-only session provides the web preview without a controller. It does not support an idle timeout. Other session types provide a controller and include a web preview. Sessions created before serve-sim was removed still return "type": "serve-sim".
示例
🌐 Example
把 appId 和 buildId 替换成你的 EAS 项目 ID 和一个兼容的构建 ID:
🌐 Replace appId and buildId with your EAS project ID and a compatible build ID:
响应
🌐 Response
返回带有新会话元数据的 200 OK:
🌐 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" } }
保存 data.id 并将其设置为剩下例子的 SESSION_ID。url 链接到 expo.dev 上的会话页面,而不是实时浏览器预览的 URL。
🌐 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 包含提供的构建 ID。applicationArchiveUrl 包含提供的归档 URL 或解析后的 Expo Go 归档 URL。使用 buildId 时,它是 null。可选值如 name、packageVersion 和 maxIdleTimeMinutes 在省略时为 null。
响应的 maxDurationMinutes 与请求的会话时长匹配。请求 30 分钟会返回 30。
🌐 The response's maxDurationMinutes matches the requested session duration. A request for 30 minutes returns 30.
remoteConfig 在会话开始时是 null。可以轮询 get endpoint 来获取状态和连接详情。
预约一次
🌐 Get a session
GET /v2/device-run-sessions/:deviceRunSessionId
返回带有与创建端点相同的会话对象的 200 OK,包括其当前状态、时间戳以及 remoteConfig。将 :deviceRunSessionId 替换为会话 ID。无需单独的连接请求。
🌐 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
这个 REST API 返回小写的状态值:
🌐 The REST API returns lowercase status values:
每五秒轮询这个端点,直到 status 是 in-progress 且 remoteConfig 不是 null,然后使用该配置进行连接。在你的集成中设置超时。如果状态变为 stopped 或 errored,停止轮询并查看 url 上的会话页面。
🌐 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
remoteConfig 中的字段取决于会话类型。只有在会话为 in-progress 时才会返回连接详情。会话停止或发生错误后,即使之前会话有连接详情,响应也会返回 remoteConfig: null。
🌐 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.
对于 agent-device,使用 URL 和令牌作为 AGENT_DEVICE_DAEMON_BASE_URL 和 AGENT_DEVICE_DAEMON_AUTH_TOKEN。对于 Argent,使用 toolsUrl 和 toolsAuthToken 作为 ARGENT_TOOLS_URL 和 ARGENT_AUTH_TOKEN。对于 Appium,用 appiumUrl 和 capabilities 配置你的客户端。有关控制器的使用,请查看 运行和控制应用。
🌐 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.
在桌面浏览器中打开 webPreviewUrl 来查看实时 iOS 模拟器或 Android 模拟器。不要在远程设备上打开。
🌐 Open webPreviewUrl in a desktop browser to view the live iOS Simulator or Android Emulator. Do not open it on the remote device.
停止会话
🌐 Stop a session
POST /v2/device-run-sessions/:deviceRunSessionId/stop
停止一个会话。这个端点不需要请求体。
🌐 Stops a session. This endpoint does not require a request body.
示例
🌐 Example
响应
🌐 Response
返回带有会话对象的 200 OK。一个活跃的会话会转变为 stopped,包括 finishedAt,并返回 remoteConfig: null。这个操作是幂等的:如果会话已经是 stopped 或 errored,它会返回该会话而不改变其状态或完成时间。连接详情保持 null。
🌐 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.
当你的工作完成时,总是停止会话,包括在出现错误或轮询超时时。HTTP 请求返回并不会停止远程设备。在你的集成中使用清理处理程序,并设置 maxDurationMinutes 来限制无人值守的使用。
🌐 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
使用返回的错误信息来确定哪个选项或权限需要关注。对于会话启动失败,请检查 url 链接的会话页面。
🌐 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
选择一个兼容的版本,连接句柄,然后与远程设备互动。