Machines API
These endpoints list your machines and do what the Machines page does: add, rename and delete machines, set their OS, and get their install and uninstall commands. Two public lists tell you which targets and Python versions you can pick.
List machines
GET /api/get_all_machines/ lists every machine on your account. It is a read.
GET /api/get_all_machines/
curl -s https://eyalsec.com/api/get_all_machines/ \
-H "X-API-Key: es2_EXAMPLEKEYdoNotUse0000000000000000000000"
{
"machines": [
["2026-07-01T00:00:00Z", "web-01", "installed", "3f6c1a52-8e0b-4d2a-9c1e-5b7d2f0a9e41",
"ubuntu_24_04_x86_64", "bc0ef13-20260604T120000Z", "bc0ef13-20260605T080000Z",
"3.13", false, false, false, false, "python"]
]
}
The machine row
Each machine is an array of 13 values in a fixed order. New values are only ever added at the end, so read by position.
| Index | Field | Meaning |
|---|---|---|
| 0 | created_at |
When you added the machine. |
| 1 | machine_name |
The name you gave it. |
| 2 | status |
created, pending, installed or failed. See status. |
| 3 | public_id |
The machine's handle in every other API call. See public id. |
| 4 | os_type |
The distribution and architecture, such as ubuntu_24_04_x86_64. |
| 5 | installed_build |
The build installed on the machine. |
| 6 | current_build |
The newest build available for this machine. When it differs from installed_build, an update is available (see build badge). |
| 7 | python_version |
The Python version the machine runs, such as 3.13 (es-python). |
| 8 | socket_only |
Retired. Machines added now always read false; some older machines may still read true. |
| 9 | clone_locked |
true when the machine's copy was seen running somewhere else. See clone. |
| 10 | stalled |
true when an install has sat in pending too long. |
| 11 | stale_agent |
true when an old copy, replaced by a reinstall, is still reporting. See old copy. |
| 12 | agent_kind |
The product the machine runs: one of the event lists' view values, such as python or browser. |
The machine's secret is never returned. You refer to a machine by its public_id.
Add a machine
POST /api/add_new_machine/ registers a new es-python or es-chromium machine. It is a write; the fields match the Add machine form.
POST /api/add_new_machine/
Form fields:
| Field | Meaning |
|---|---|
machine_name |
Required. The display name. |
product |
python (the default) or browser. You must have that product on your account (403 otherwise). |
distro, arch |
Required for python: combined into the os_type, such as ubuntu_24_04 and x86_64. Unused for browser. See supported targets. |
python_version |
python only. Defaults to 3.13. Must be available for that target (see Python versions); a version that exists but is not available for the target is a 422 naming both. |
curl -s https://eyalsec.com/api/add_new_machine/ \
-H "X-API-Key: es2_EXAMPLEKEYdoNotUse0000000000000000000000" \
-d machine_name=web-01 -d distro=ubuntu_24_04 -d arch=x86_64
The answer is 200 with the new machine:
{ "Name": "web-01", "OsType": "ubuntu_24_04_x86_64", "Status": "created",
"PublicID": "0b9d7e21-4c3a-4f5e-8a61-2d9c0e7f1b53", "PythonVersion": "3.13", "SocketOnly": "false",
"AgentKind": "python" }
An es-chromium machine (product=browser) needs only a name, and its answer leaves out the es-python fields:
{ "Name": "test-browser", "OsType": "", "Status": "created",
"PublicID": "0b9d7e21-4c3a-4f5e-8a61-2d9c0e7f1b53", "AgentKind": "browser" }
Your machine limit is counted per product, so a full es-python allowance does not use up your es-chromium one. At the limit the answer is 409; an account with no plan yet has a limit of 0. Other errors: 422 for a missing or invalid field, an unknown target or Python version; 403 for a product your account does not have. SocketOnly is always "false", and a socket_only field you send is ignored.
The es-chromium install command
The es-chromium install command comes from the Machines page. Getting it needs your signed-in dashboard session and cannot be done with an API key.
Set a machine's OS
POST /api/set_machine_os/ changes the distribution and architecture a machine is installed for. It is a write; see Set OS.
POST /api/set_machine_os/
Form fields: machine_name (the display name), distro and arch, all required. An unknown target is a 422, and a name that is not one of your machines is a 404.
curl -s https://eyalsec.com/api/set_machine_os/ \
-H "X-API-Key: es2_EXAMPLEKEYdoNotUse0000000000000000000000" \
-d machine_name=web-01 -d distro=debian_12 -d arch=aarch64
{ "machine_name": "web-01", "os_type": "debian_12_aarch64" }
Rename a machine
POST /api/rename_machine/ gives a machine a new display name. It is a write; see Rename.
POST /api/rename_machine/
JSON body: public_id and machine_name, both required. The name is trimmed and must then be 1 to 128 characters (422 otherwise). A machine that is not yours is a 404.
curl -s https://eyalsec.com/api/rename_machine/ \
-H "X-API-Key: es2_EXAMPLEKEYdoNotUse0000000000000000000000" \
-H "Content-Type: application/json" \
-d '{"public_id":"3f6c1a52-8e0b-4d2a-9c1e-5b7d2f0a9e41","machine_name":"db-primary"}'
{ "public_id": "3f6c1a52-8e0b-4d2a-9c1e-5b7d2f0a9e41", "machine_name": "db-primary" }
Delete a machine
POST /api/delete_machine/ removes a machine and every event it reported. It is a write, it cannot be undone, and it answers 204 with no body. See Delete.
POST /api/delete_machine/
JSON body: public_id. A machine that is not yours is a 404.
curl -s https://eyalsec.com/api/delete_machine/ \
-H "X-API-Key: es2_EXAMPLEKEYdoNotUse0000000000000000000000" \
-H "Content-Type: application/json" \
-d '{"public_id":"3f6c1a52-8e0b-4d2a-9c1e-5b7d2f0a9e41"}'
Get the install command
POST /api/get_eyalsec_install_script_data/ issues a one-time install secret for an es-python machine, the same thing the Machines page does when you ask for the install command. It is a write.
POST /api/get_eyalsec_install_script_data/
JSON body: public_id, and attested, which must be true. attested is your confirmation that you are authorized to monitor that machine, the same box the dashboard asks you to tick (see authorization).
curl -s https://eyalsec.com/api/get_eyalsec_install_script_data/ \
-H "X-API-Key: es2_EXAMPLEKEYdoNotUse0000000000000000000000" \
-H "Content-Type: application/json" \
-d '{"public_id":"3f6c1a52-8e0b-4d2a-9c1e-5b7d2f0a9e41","attested":true}'
{ "secret": "<single-use-secret>", "script_path": "https://eyalsec.com/install.sh",
"os_type": "ubuntu_24_04_x86_64" }
The secret works once and expires after 10 minutes. On the machine, the install command posts it to script_path; the Machines page shows the exact command to run. Errors: 422 when attested is missing or false or the machine has no OS set, 404 for a machine that is not yours, 403 for a product your account does not have.
Reinstall or update
There is no separate reinstall endpoint: reinstalling is installing again. Call the same endpoint; if the machine is installed, pending or failed, it is first reset to created and then given a fresh secret. See Reinstall.
The reset clears the recorded install time, build and clone identity, and cancels any unused install secrets. The machine's name, public_id, configuration and events are kept. The copy already on the machine keeps reporting until the new install actually starts.
Get the uninstall command
POST /api/get_uninstall_script_data/ issues a one-time secret for removing es-python from a machine, the same command the Machines page shows under Uninstall. It is a write.
POST /api/get_uninstall_script_data/
JSON body: public_id.
curl -s https://eyalsec.com/api/get_uninstall_script_data/ \
-H "X-API-Key: es2_EXAMPLEKEYdoNotUse0000000000000000000000" \
-H "Content-Type: application/json" \
-d '{"public_id":"3f6c1a52-8e0b-4d2a-9c1e-5b7d2f0a9e41"}'
{ "secret": "<single-use-secret>", "script_path": "https://eyalsec.com/uninstall.sh" }
The secret works once and expires quickly. This is for es-python machines only: the command removes es-python and nothing else, so an es-chromium machine is a 422 (delete the machine instead).
Supported targets
GET /api/supported_os_types/ lists the distributions and architectures you can install es-python on. It is public: it needs no key.
GET /api/supported_os_types/
{ "distros": [ { "id": "ubuntu_24_04", "label": "Ubuntu 24.04 LTS",
"archs": ["x86_64", "aarch64"] } ] }
A machine's os_type is a distro id and an arch joined by _, such as ubuntu_24_04_x86_64.
Python versions
GET /api/supported_python_versions/ lists the Python versions you can pick when adding a machine, and the default. It is public: it needs no key.
GET /api/supported_python_versions/?os=ubuntu_24_04_x86_64
{ "versions": ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"], "default": "3.13" }
Without os it lists every version es-python supports. With os it lists only the versions available for that target, which is what POST /api/add_new_machine/ accepts for it, so always pass os before creating a machine. The default is always one of the listed versions: when the usual default is not available for the target, it is the newest one that is. An unknown os is a 422.