Snapshots API
List snapshots, boot new devices from them, and delete them. Snapshots are created from a device with POST /v1/devices/:id/snapshot.
Read Snapshots first: snapshots are pinned to the host that took them, have per-plan quotas, and can be lost. To create one, use POST /v1/devices/:id/snapshot.
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"
}| Field | Type | Description |
|---|---|---|
id |
string | snp_… |
device_id |
string | The device it was taken from. |
node_id |
string | The host that stores it. Restored devices are placed on this host. |
name |
string or null | Your label. |
size_bytes |
integer or null | Size on disk, once ready. |
status |
string | pending, ready, error or lost. |
created_at |
string | When it was taken. |
List snapshots#
/v1/snapshotsReturns a JSON array of your snapshots (the 200 most recent, deleted ones excluded), newest first.
curl https://akaphone.abhgnx-417.workers.dev/v1/snapshots \
-H "Authorization: Bearer $AKAPHONE_API_KEY"const snapshots = await fetch("https://akaphone.abhgnx-417.workers.dev/v1/snapshots", {
headers: { Authorization: `Bearer ${process.env.AKAPHONE_API_KEY}` },
}).then((r) => r.json());
const ready = snapshots.filter((s: { status: string }) => s.status === "ready");import os, requests
snapshots = requests.get(
"https://akaphone.abhgnx-417.workers.dev/v1/snapshots",
headers={"Authorization": f"Bearer {os.environ['AKAPHONE_API_KEY']}"},
).json()Response 200 OK
[
{ "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" }
]Restore a snapshot#
/v1/snapshots/:id/restoreCreates a new device from a ready snapshot. Equivalent to POST /v1/devices with snapshot_id, and subject to the same credit, concurrency and rate limits.
| Body field | Type | Default | Description |
|---|---|---|---|
name |
string | null |
Name for the new device. |
profile |
string | "pixel_8" |
Screen profile for the new device. |
android |
string | "14" |
Android version. |
wait |
boolean | false |
Hold the request until the device is running (max 90 s). |
?wait=true&timeout=<seconds> works too.
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}'const device = await fetch("https://akaphone.abhgnx-417.workers.dev/v1/snapshots/snp_01m5vqsywgez2ntdv5fq42/restore", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.AKAPHONE_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({ name: "run-1842", wait: true }),
}).then((r) => r.json());device = requests.post(
"https://akaphone.abhgnx-417.workers.dev/v1/snapshots/snp_01m5vqsywgez2ntdv5fq42/restore",
headers={"Authorization": f"Bearer {os.environ['AKAPHONE_API_KEY']}"},
json={"name": "run-1842", "wait": True},
).json()Response 201 Created with the new device:
{ "id": "dev_qj196bgdqs10", "name": "run-1842", "status": "running", "profile": "pixel_8", "android": "14", "region": "eu-central", "node_id": "nod_01m5vqsywg84jv64rmmqf9", "snapshot_id": "snp_01m5vqsywgez2ntdv5fq42", "created_at": "2026-10-26T10:02:17.000Z", "ready_at": "2026-10-26T10:02:21.000Z", "terminated_at": null, "last_activity_at": "2026-10-26T10:02:17.000Z", "billed_minutes": 1, "error": null }| Error | When |
|---|---|
404 not_found |
Unknown or deleted snapshot. |
409 conflict |
The snapshot is lost (Snapshot was lost with the host that stored it and cannot be restored), or is pending or error. |
402 insufficient_credits |
Balance below 1. |
409 concurrency_limit |
Plan device limit reached. |
429 rate_limited |
More than 10 device creations in a minute. |
If the snapshot's host is full, the device stays queued until a slot frees up there, and goes to error with no_capacity after 10 minutes.
Delete a snapshot#
/v1/snapshots/:idDeletes the snapshot and frees its quota slot. The host removes the image in the background. Devices already restored from it keep running.
curl -X DELETE https://akaphone.abhgnx-417.workers.dev/v1/snapshots/snp_01m5vqsywgez2ntdv5fq42 \
-H "Authorization: Bearer $AKAPHONE_API_KEY"await fetch("https://akaphone.abhgnx-417.workers.dev/v1/snapshots/snp_01m5vqsywgez2ntdv5fq42", {
method: "DELETE",
headers: { Authorization: `Bearer ${process.env.AKAPHONE_API_KEY}` },
});requests.delete(
"https://akaphone.abhgnx-417.workers.dev/v1/snapshots/snp_01m5vqsywgez2ntdv5fq42",
headers={"Authorization": f"Bearer {os.environ['AKAPHONE_API_KEY']}"},
)Response 204 No Content. 404 not_found if it does not exist or was already deleted.