---
title: "Write a stored blob onto a machine"
method: POST
path: "/api/v1/push"
---

# Write a stored blob onto a machine

`POST /api/v1/push`

## Request

- Base URL: `https://aicommander.dev`
- URL: `https://aicommander.dev/api/v1/push`
- Auth: HTTP bearer

PRO ONLY: Free and anonymous callers cannot initiate pushes, and a plan-restricted machine fails with reason `plan_device_limit`. Writes a blob already held by the relay to absolute `dest_path`. A blob created before downgrade remains usable only until its original 24-hour TTL. The write is atomic but REPLACES an existing file; ordinary mode and, where possible, owner/group are preserved, while setuid/setgid/sticky are dropped and symlinks donate no metadata. New files are 0600. The machine refuses more than 100 MiB or insufficient free space before transfer. The relay answers within about 55 seconds. Allowed Pro transfers share the 60/hour/account transfer count; push does not recharge the 5 GiB storage budget because the bytes are already stored.

## Request body

- object
  - `code` string, required
  - `blob_id` string, required: 32 hex characters, from /api/v1/pull or POST /api/v1/files.
  - `dest_path` string, required: ABSOLUTE destination path. The parent directory must already exist; an existing file is REPLACED.

## Response `200`

The file was written to the machine.

- object
  - `ok` true, required
  - `bytes` integer, required
  - `destPath` string, required

## Other responses

- `400`: Missing/invalid fields. On the job endpoints this is also how the MACHINE reports a request it can never run (`reason: "invalid_request"` — an empty command, a relative `cwd`, a `gpu_index` that names no card): the request itself is at fault, so correct the field the message names rather than retrying it.
- `401`: A token was supplied but is not a valid API key/admin/OAuth token.
- `403`: Resolved but refused. Causes include expired anonymous access; Free/anonymous file transfer; `reason: plan_device_limit`; independent operator block/approval; or `error: reactivation_required`. For plan_device_limit, delete an older saved machine to promote the next or upgrade to Pro. For file transfer, use Pro. Do not conflate either with operator approval.
- `404`: Session code or alias not found (anonymous callers get a unified message that does not confirm existence).
- `429`: After the Pro entitlement gate, a transfer quota (`reason: rate_limited`) or per-IP/global call limit was exceeded: 60 transfers/hour/account, 10000/hour relay-wide, and 5 GiB/account/rolling day for uploads and pulls. Push spends only the hourly count. Pull reserves 100 MiB until settlement, so low headroom or concurrency can refuse a smaller file. Wait for the window or use storage the user controls.
- `503`: The session exists but the agent is offline or disconnected mid-command.

---

[API](https://skmtc.dev/aicommander/apis/ai-commander-remote-shell-and-long-running-jobs-api.md) · [All operations](https://skmtc.dev/aicommander/apis/ai-commander-remote-shell-and-long-running-jobs-api/llms.txt) · [OpenAPI document](https://skmtc.dev/aicommander/apis/ai-commander-remote-shell-and-long-running-jobs-api/revisions/a6bb89f779a1?raw)
