Skip to main content

Create a Pod

Request Body:
Response: 202 Accepted Returns the Pod object with status: "creating". Errors:

Create a Pod From a Repo

Creates a pod for a GitHub repository, attaches the repo, and deploys it once the pod is up. See Git Deployment. Request Body:
Two read-only endpoints support this flow:

Create a Pod From a ZIP

Creates a pod from an uploaded project archive, then installs dependencies and runs the production build on the pod. multipart/form-data, not JSON. The archive needs a package.json or an index.html at its top level, or the request is rejected with 400 - that’s how the runtime is detected.

Re-upload to an Existing Pod

Replaces the source of a pod created by upload and rebuilds it in place - same URL, plan and environment. Same multipart zip field and 128MB limit. A stopped pod is started first. Returns 400 if the archive detects as a different runtime than the pod runs; create a new pod for that.

List Pods

Response: 200 OK

Get a Pod

Returns the Pod object with live status synced from the container runtime.

Delete a Pod

Response: 200 OK
Pod names are reserved for 7 days after deletion to prevent SSH host key conflicts. Creating a pod with a recently deleted name will return a conflict error.

Start / Stop / Restart

No request body. Returns the updated Pod object.

Reload

Restarts app services inside the pod. Auto-installs dependencies if package.json (Node.js) or requirements.txt (Python) is detected. Response: 200 OK

Resize

Request Body:
Returns the updated Pod object with new CPU, memory, and disk values from the plan.

Clone

Request Body:
Response: 201 Created — returns the new Pod object.

Apply a Deploy Doctor Fix

Applies the fix for the pod’s current Deploy Doctor diagnosis. Owner-only, and only ever on this explicit call - a diagnosis alone never changes a pod. No request body. The diagnosis itself decides what runs: re-pointing the proxy at the port the app is really on, rewriting the start command, reinstalling dependencies, switching the Node major, or converting the pod to a worker. Response: 200 OK
The pod’s diagnosis is on the pod object as app_health_diagnosis, a JSON string with class, title, detail, fix, auto_fixable, confidence and - when a one-click fix exists - fix_action.

Switch Node Version

Switches a Node.js pod to a different Node major in place, keeping files, environment, domain and plan. Owner-only, Node.js pods only. Request Body:
Supported majors: 18, 20, 22, 24. Response: 200 OK
The install runs in the background, so this returns immediately. Returns 400 if the pod isn’t a Node.js pod, is already on that version, or the version isn’t supported.

Get Preset Config

Returns the preset configuration for this pod (port, app root, public root, runtime details).

Get Disk Usage

Returns current disk usage statistics for the pod.

Run a Command

Runs a command inside the pod and returns its output. This is the same thing instapods exec uses, so it needs no SSH key. The pod must be running. Request Body:
Pass the command as an array, not a string. Each element is escaped before it reaches the pod, so an argument containing spaces (a quoted SQL statement, a bash -c script) arrives intact. Response: 200 OK
A command that fails still returns 200 - the non-zero exit is reported in the body, because the output is usually the thing you wanted:
The command runs as the instapod user, matching what you get over SSH. Returns 400 if the pod isn’t running, command is empty, or workdir is outside the allowed directories.

Environment Variables

Reads and writes the pod’s dotenv file. See Environment Variables for how the file is wired into each preset.

Get Variables

Response: 200 OK
path is the file the values were read from, which differs per preset and per 1-Click App. A pod that has no env file yet returns an empty vars object rather than a 404.

Set Variables

Merges into the existing file: keys you send are updated or appended, keys you don’t send are left alone. Comments and blank lines in the file survive the edit. Response: 200 OK
Returns 400 if vars is missing or empty.
Writing the file does not restart your app. Call POST /api/pods/{name}/reload (or restart the pod) for the new values to be picked up.

Unset Variables

Returns 400 if keys is missing or empty, and 404 if the pod has no env file.

Logs

Reads the pod’s journal. Response: 200 OK
Two behaviours of the underlying journalctl carry through and are worth knowing:
  • Smart case. An all-lowercase grep pattern matches case-insensitively; a pattern containing any uppercase character matches case-sensitively.
  • Order. A filtered read returns newest first, the opposite of an unfiltered tail.
grep takes a PCRE2 pattern, and it filters the search rather than the tail: you get the last lines matching entries, not the matches within the last lines. A search that matches nothing is a success, not an error - the body carries journald’s own -- No entries --. A pattern that doesn’t compile returns 400 with the parser’s complaint.

Events

The pod’s activity trail - what the dashboard’s Activity tab renders. Response: 200 OK
Event type covers the pod lifecycle (created, started, stopped, restarted, resized, reloaded, deleted), services (service_install, service_running, service_removed), Git (git_connected, git_disconnected, deployment, deploy_failed), domains (domain_added, domain_removed, domain_verified), SSH keys (ssh_key_added, ssh_key_removed), environment changes (env_updated), and status (error, progress). Treat the list as open-ended - new types are added as features ship.
A deploy that fails is logged as deploy_failed, not deployment. If you are matching on deployment to find deploys, you will only see the successful ones.

Event Metadata

metadata is an optional JSON string carrying structured context for the event. It is omitted entirely when there is nothing to record, so check before parsing. The message is prose written for a human reading the Activity tab. metadata is what you group and query by, so a failure’s cause never has to be parsed back out of English. Deploy events carry: class is present on every failed deploy. When the failure matched no known signature it is the literal string unknown rather than being left out, so you can count unexplained failures rather than inferring them from absence.

Metrics

The most recent sample. Returns null if none has been recorded yet, so check before reading fields.
cpu_usage and memory_usage are percentages of the pod’s own plan allocation. storage_used, network_in and network_out are bytes.

Metrics History

Returns an array of the same objects, oldest first. This is what the Metrics tab charts.

AI Coding Agents

Installs a terminal coding agent inside the pod, so you can run it over SSH or in the web terminal against your own code. The same thing is available on the pod’s Dev Tools tab and from the CLI as instapods agents.

List the Catalog

Every agent you can install, with the presets each one supports.

List Installed Agents

Agent statuses: installing, installed, error. An error entry carries error_msg.

Install an Agent

Response: 202 Accepted - returns the agent record with status: "installing". The install runs in the background, so poll GET /api/pods/{name}/agents until the status settles.
Agents are installed, not configured. You still sign in to the agent yourself (with your own API key or account) the first time you run it inside the pod. InstaPods never holds those credentials.

Remove an Agent

Response: 200 OK

Pod Object

All pod endpoints return this shape:
Pod statuses: creating, running, stopped, deleted, error, suspended