Profiles
Read, create, update, and delete shell profiles — the named launch definitions (executable, arguments, environment, working directory) that TermFlow uses when it opens a new terminal.
Base URL: http://127.0.0.1:42031/api (prod). Every endpoint on this page is served by TermFlow's local REST API.
In the default localhost-only mode these endpoints are unauthenticated — that is safe because the server is bound to 127.0.0.1. A bearer token is required only when you turn on "Expose on local network" in Settings → Connections. See API overview and auth for the full model.
What a profile is
TermFlow detects the shells installed on your machine (for example your default login shell, PowerShell, WSL distros) and exposes each as a profile. You can also define your own custom profiles. When a new tab or pane is created — from the UI, the REST API, or an MCP client — it launches the executable named by the chosen profile.
Profiles are referenced by their id when you create a terminal (the profileId / profile field in POST /api/terminals, or the profile argument to the MCP create_terminal tool).
The Profile object
{
"id": "custom-1720099200000",
"name": "Dev Shell",
"path": "/bin/zsh",
"args": ["-l"],
"env": { "TERM_PROGRAM": "termflow" },
"cwd": "/home/me/projects",
"icon": null,
"is_default": false,
"is_custom": true
}
| Field | Type | Notes |
|---|---|---|
id | string | Stable identifier. Detected shells have system-assigned ids; custom profiles are assigned custom-<timestamp-ms> on creation. |
name | string | Display name shown in the tab / profile dropdown. |
path | string | Path to the shell executable to launch. |
args | string[] | Command-line arguments passed to the executable. |
env | object | Extra environment variables as string → string pairs, merged into the launched process. |
cwd | string | null | Optional "start in" directory. Omitted/null means inherit the default. |
icon | string | null | Optional icon hint; null when unset. |
is_default | boolean | Whether this profile is used for new tabs when none is specified. |
is_custom | boolean | true for user-created profiles, false for auto-detected system shells. |
Endpoints
| Method | Path | Purpose |
|---|---|---|
GET | /api/profiles | List all profiles (detected + custom). |
POST | /api/profiles | Create a custom profile. |
GET | /api/profiles/:id | Fetch one profile by id. |
PUT | /api/profiles/:id | Update a custom profile. |
DELETE | /api/profiles/:id | Delete a custom profile. |
PUT and DELETE operate on custom profiles only. Auto-detected system shells (is_custom: false) are read-only: they appear in GET responses but cannot be updated or deleted, and attempting to do so returns 404.
GET /api/profiles
Returns every profile wrapped in a profiles array.
GET /api/profiles HTTP/1.1
Host: 127.0.0.1:42031
{
"profiles": [
{ "id": "system-zsh", "name": "zsh", "path": "/bin/zsh", "args": [], "env": {}, "cwd": null, "icon": null, "is_default": true, "is_custom": false },
{ "id": "custom-1720099200000", "name": "Dev Shell", "path": "/bin/zsh", "args": ["-l"], "env": {}, "cwd": "/home/me/projects", "icon": null, "is_default": false, "is_custom": true }
]
}
GET /api/profiles/:id
Looks up a single profile by its exact id (not by name) and returns the bare object.
{
"id": "system-zsh",
"name": "zsh",
"path": "/bin/zsh",
"args": [],
"env": {},
"cwd": null,
"icon": null,
"is_default": true,
"is_custom": false
}
If no profile matches the id, the response is 404:
{ "error": "Profile not found" }
POST /api/profiles
Creates a new custom profile. The server generates the id, forces is_custom to true, and sets is_default to false — those three fields are ignored if you send them.
Request body
| Field | Type | Required | Default |
|---|---|---|---|
name | string | yes | — |
path | string | yes | — |
args | string[] | no | [] |
env | object | no | {} |
cwd | string | no | — |
icon | string | no | — |
curl -X POST http://127.0.0.1:42031/api/profiles \
-H "Content-Type: application/json" \
-d '{
"name": "Dev Shell",
"path": "/bin/zsh",
"args": ["-l"],
"env": { "TERM_PROGRAM": "termflow" },
"cwd": "/home/me/projects"
}'
On success the response is 201 Created with the generated id:
{ "id": "custom-1720099200000", "status": "created" }
PUT /api/profiles/:id
Replaces the fields of an existing custom profile. The body uses the same shape as POST (name and path required; args / env / cwd / icon optional).
curl -X PUT http://127.0.0.1:42031/api/profiles/custom-1720099200000 \
-H "Content-Type: application/json" \
-d '{ "name": "Dev Shell (login)", "path": "/bin/zsh", "args": ["-l", "-i"] }'
{ "status": "updated" }
If the id does not match a custom profile, the response is 404:
{ "error": "Custom profile not found" }
DELETE /api/profiles/:id
Removes a custom profile.
curl -X DELETE http://127.0.0.1:42031/api/profiles/custom-1720099200000
{ "status": "deleted" }
A non-existent or non-custom id returns 404:
{ "error": "Custom profile not found" }
Setting the default profile
An honest note: There is currently no working REST endpoint for changing which profile is the default. Both
POSTandPUTwriteis_default: false, so the flag cannot be set through this API. Choose the default profile in Settings → Shell Profiles instead, where you can also set a per-profile "Start In Directory". Custom profiles created here persist across restarts.
Notes
GET /api/profilesis a wrapper object ({ "profiles": [...] }), whileGET /api/profiles/:idreturns the bare object. Parse each accordingly.- Detected system shells are computed fresh from your machine on each
GET; custom profiles are persisted to TermFlow's config folder and survive restarts. - Profile
idvalues are what you pass asprofileId/profilewhen creating a terminal — see Terminals.
Next steps
- Terminals — use a profile's
idto open a terminal. - Shell profiles (settings) — manage profiles and pick the default in the UI.