Real devices, not emulators
The fleet is in France, with its real manufacturers, real networks and real fonts. An emulator renders your page the same way for everyone; a Redmi running MIUI does not.
You open a session and the phone shows up in the tab: you touch, you type, you install your APK. On close, the device is reset — the previous customer's APK is gone.
No credit card to start. Secure payment through Stripe when you change plan.

Real capture: the fleet Redmi screen, relayed into the viewer.
This is not a lab estimate: it is a real session, on a real device, read in the browser. The H.264 stream crosses Tactile byte for byte — the relay does not rewrite it, it copies it.
400 unsupported_target.adb shell: only the toolbar actions, all reversible.No, not in v1: only the toolbar actions (touch, keyboard, system buttons, rotation, volume, APK upload, screenshot, opening a URL). The shell will come later, as an allow-list of commands.
No: a platform `capture` requires a target (`package` or `url`); there is no "capture the current screen" job. Without a target, Tactile answers `400 unsupported_target` instead of pretending. The viewer itself snapshots the view displayed in the browser, without a job.
No: `GET /api/v1/sessions/:id/logcat` requires a `package` and relaunches the targeted app with a filter. No control action gives access to the shell — on purpose.
Not in phase 1: time-slot bookings, the back office and the clipboard are out of scope. The simultaneous session ceiling (`max_parallel`) is stored on the key but not enforced.
No: rented devices are connected to no personal Google account — a service account per device, or none. A session therefore leaves nothing behind.
The fleet is in France, with its real manufacturers, real networks and real fonts. An emulator renders your page the same way for everyone; a Redmi running MIUI does not.
Tactile is the only product in the family measured end to end on a real device: 145 frames / 219 kB in 6 s (~30 fps), `session.ready` 460 × 1024, `avc1.640020` rebuilt from the SPS. The H.264 stream is relayed byte for byte.
The browser only ever sees an opaque session token; the customer lease is replaced by the lease of their session. That is what stops one customer from watching or driving another one's device.
On close, a `reset` job uninstalls the customer APK, clears downloads and signs out the accounts added during the session. The next customer finds no trace of the previous one.
Five minutes idle: warning, then close. Browser killed abruptly: the lease is released in under 60 s (a 10 s grace period plus a sweep), and minutes are only charged once.
Billing follows the open → closed state transition: a double call (the `DELETE` route and then the sweeper) does not charge twice. A credit ceiling stops the session before the surprise.
Every browser gesture becomes a precise action on the device. Nothing goes through a shell: these are control events, so nothing can stay broken after your session.
| In the browser | On the device |
|---|---|
| Click or tap on the screen | touch down then up, at video coordinates; scrcpy scales them back to the real screen. |
| Drag | touch down + move (at most one every 30 ms) + up: the gesture leaves continuously, not as a jump. |
| Wheel | scroll, clamped to ±20 units per event. |
| Typing | letters leave as text; Enter (66), Back (67), Delete (112), arrows, Tab and Escape → Back leave as key. |
| Ctrl+V | the clipboard, truncated to 500 characters. |
| “Text to type” field + Send | up to 2,000 characters at once, without going through the virtual keyboard. |
| Toolbar | Home, Back, Recents, Rotate, Volume +/−, Power, Wake: system key codes, not shell. |
| Capture and Stats | browser side: a snapshot of the displayed view and the counters (decoded frames, decoder queue, WebSocket, billing). |
| Close | releases the device, triggers the reset and charges the minutes consumed — once only. |
A product that hides its limits wastes everybody's time. Here are ours, today.
Create an account, take a key, open a device from the fleet. The trial gives 60 minutes, no credit card.