Requirements
Network inspection must be enabled for the device’s hosting pool. Contact Mobilerun support at contact@mobilerun.ai if you need access.
true. The capability is granted when a device is placed in an enabled pool. Disabling inspection for that pool also prevents new sessions and stops active sessions.
Endpoints
Use your Mobilerun API key for the REST endpoints. Non-browser WebSocket clients also authenticate with that API key. Browser clients, which cannot set an
Authorization header on WebSocket, use the existing device stream token returned in stream.token as a token query parameter. Always start with the returned stream.url instead of constructing the path yourself.
Start an inspection session
Create a session with a uniqueIdempotency-Key so retrying the same request does not start another session:
starting, active, or stopping for a device at a time. Starting another returns 409 TRAFFIC_ALREADY_ACTIVE.
Wait until the session is active
Starting inspection is asynchronous. Poll the status endpoint until the device producer is ready:starting or active, the status response returns the device’s existing stream token. This is the same device-bound credential used by other device WebSocket endpoints; it is not a traffic-specific or session-scoped viewer token. It is revoked when the device is terminated and rotates when device ownership changes. Treat it as a secret and do not log URLs containing it.
Stream events with websocat
Open the returned WebSocket URL with your Mobilerun API key and the required subprotocol:stream.token as a Bearer token. For non-browser clients, the Bearer credential is your dr_sk_... API key.
The websocat options keep large JSON events intact when piping them into jq, including on macOS.
Browser WebSocket clients
The browserWebSocket API cannot set an Authorization header. Add the returned device stream token to the returned URL instead:
starting or active.
Exercise the app on the device while this command is running. Each line is a JSON event. The first event is hello; subsequent event types are:
Event schema
Stream hello
The gateway sends ahello message immediately after the WebSocket opens. This message uses camelCase fields and is separate from the device event envelope:
Device event envelope
All subsequent device events use snake_case fields:
The ingest boundary rejects undeclared or duplicate fields, malformed Base64, negative numeric values, and payloads that exceed the session body limit.
A
ready event has no additional fields:
Flow events
Aflow event adds a flow object. Only id and decryption_status are always present; other fields can be omitted or null when an interception fails before that information is available.
There is no combined
url field. Construct one from scheme, host, optional port, and path if your parser needs it.
A null body field means that no body bytes were captured. Use the corresponding *_body_bytes and *_body_truncated fields to distinguish an empty body from one clipped by the session limit.
WebSocket message events
Application WebSocket messages refer back to their HTTP upgrade flow byflow_id:
Gap events
Agap event reports that the device queue dropped one or more events:
dropped_events is a required positive integer. The event does not identify which flows or messages were dropped.
For example, decode response bodies with jq:
Interception behavior
Inspection is transparent at the device-networking layer. You do not need to configure an HTTP proxy in the app or Android settings. Starting a session temporarily installs the capture CA and reconfigures the device’s existing TUN routing; stopping the session restores the previous routing and trust-store mounts. Android’s globalhttp_proxy setting is neither required nor modified.
Certificate pinning is not bypassed. A pinned app can reject the inspection certificate before an HTTP request is available, causing the connection to fail without a decoded flow. If the failure reaches the HTTP flow pipeline, the stream reports decryption_status: "failed" with an error, but clients should not assume every rejected TLS handshake produces an event. Keep using an authorized Frida pinning bypass, or equivalent instrumentation for a native or custom trust store, when inspecting pinned apps.
Stop the session
Stop inspection when you are finished so the device can restore its normal routing and temporary trust changes:202 Accepted while cleanup runs. Repeating it is safe. Sessions also stop automatically when they expire.
Troubleshooting
TRAFFIC_NOT_SUPPORTED— The device image does not support network inspection.TRAFFIC_NOT_ENTITLED—capabilities.trafficInspectionisfalse; create a device in an enabled pool or contact support.TRAFFIC_ALREADY_ACTIVE— Another session is starting, active, or stopping. Use the session ID indetails.sessionId, or list sessions withGET /devices/{deviceId}/traffic/sessions.TRAFFIC_DEVICE_NOT_READY— Wait until the device reaches thereadystate and retry with the same idempotency key.401 Unauthorizedon the WebSocket — For CLI clients, send yourdr_sk_...API key asAuthorization: Bearer .... For browsers, append the returnedstream.tokenas the URL’stokenquery parameter. Do not sendstream.tokenas a Bearer token.- WebSocket subprotocol error — Send
Sec-WebSocket-Protocol: mobilerun.traffic.v1with either authentication method. Incoming message too longor ajqparse error — Increasewebsocat’s message buffer with-B; do not use-S, because strict mode drops oversized inspection events. Use--no-async-stdiowhen piping large messages on macOS.- The socket closed with
1013— Reconnect with the same authentication method. Read the session status again first if the device may have been transferred or replaced. Missed events are not replayed.