Snapshots
Save a device's disk (apps, logins, settings) and boot new devices from it. Snapshots are pinned to the host that took them, have per-plan quotas, and can be lost with their host.
A snapshot saves the disk of a running device: installed apps, their data and logins, system settings. You can then boot any number of new devices from it, each starting exactly where the snapshot left off. The original device is not affected.
Typical uses:
- Install your app and sign in to a test account once, then start every test run from that state.
- Prepare a device with a specific language, region or accessibility setting (see Localisation testing).
- Keep a known-good state to compare against after a release.
Take a snapshot#
The device must be running.
curl -X POST https://akaphone.abhgnx-417.workers.dev/v1/devices/dev_s6zr7mr4f2f1/snapshot \
-H "Authorization: Bearer $AKAPHONE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "signed-in-v2.3"}'const snap = await fetch("https://akaphone.abhgnx-417.workers.dev/v1/devices/dev_s6zr7mr4f2f1/snapshot", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.AKAPHONE_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({ name: "signed-in-v2.3" }),
}).then((r) => r.json());import os, requests
snap = requests.post(
"https://akaphone.abhgnx-417.workers.dev/v1/devices/dev_s6zr7mr4f2f1/snapshot",
headers={"Authorization": f"Bearer {os.environ['AKAPHONE_API_KEY']}"},
json={"name": "signed-in-v2.3"},
).json()The response is 202 with the snapshot in pending status. It becomes ready when the host has finished writing it; poll GET /v1/snapshots to see the change. In the MCP server, the tool is device_snapshot.
Restore#
Restoring creates a new device from the snapshot:
curl -X POST https://akaphone.abhgnx-417.workers.dev/v1/snapshots/snp_01m5vqsywgez2ntdv5fq42/restore \
-H "Authorization: Bearer $AKAPHONE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "run-1842", "wait": true}'This is the same as POST /v1/devices with snapshot_id set, and it accepts the same body (name, profile, android, wait). The snapshot must be ready. The new device counts toward your concurrency limit and bills like any other device.
Pinned to one host#
In this version a snapshot is stored on the disk of the host that took it, and every device restored from it is placed on that same host. node_id on the snapshot tells you which host it is. This has three consequences:
- Restores can queue. If that host has no free slot, the new device waits in
queuedeven when other hosts are idle. After 10 minutes it gives up witherror: "no_capacity". - Snapshots can be lost. If the host fails permanently, its snapshots move to status
lostand cannot be restored (409 conflict: Snapshot was lost with the host that stored it). Devices created from a lost snapshot are not affected once they are running. - Snapshots can be refused. A host that is low on disk refuses new snapshots with
409 conflict(Device host is low on disk; try again later).
Treat snapshots as a convenient cache, not a backup. Keep whatever you need to rebuild the state (APK, test account, setup task) so you can recreate a snapshot if it is lost. Moving snapshots to shared storage, so any host can restore them, is on the roadmap.
Statuses#
| Status | Meaning |
|---|---|
pending |
Being written by the host. Counts toward your quota. |
ready |
Can be restored. Counts toward your quota. |
error |
The host could not write it. Does not count. |
lost |
Its host is gone. Cannot be restored. Does not count. |
deleted |
You deleted it. Not listed. |
Quotas#
| Plan | Snapshots you can hold (pending + ready) |
|---|---|
| Free | 1 |
| Dev | 5 |
| Team | 20 |
Taking one more returns 409 conflict (Snapshot quota reached); delete one first with DELETE /v1/snapshots/:id. Separately, you can take at most 5 snapshots per hour (429 rate_limited). Snapshot storage is not billed.
The snapshot object#
{
"id": "snp_01m5vqsywgez2ntdv5fq42",
"device_id": "dev_s6zr7mr4f2f1",
"node_id": "nod_01m5vqsywg84jv64rmmqf9",
"name": "signed-in-v2.3",
"size_bytes": 1873215488,
"status": "ready",
"created_at": "2026-10-26T09:20:44.000Z"
}size_bytes is null until the snapshot is ready. Full endpoint reference: Snapshots API.