Skip to main content

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.

Auth

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
}
FieldTypeNotes
idstringStable identifier. Detected shells have system-assigned ids; custom profiles are assigned custom-<timestamp-ms> on creation.
namestringDisplay name shown in the tab / profile dropdown.
pathstringPath to the shell executable to launch.
argsstring[]Command-line arguments passed to the executable.
envobjectExtra environment variables as string → string pairs, merged into the launched process.
cwdstring | nullOptional "start in" directory. Omitted/null means inherit the default.
iconstring | nullOptional icon hint; null when unset.
is_defaultbooleanWhether this profile is used for new tabs when none is specified.
is_custombooleantrue for user-created profiles, false for auto-detected system shells.

Endpoints

MethodPathPurpose
GET/api/profilesList all profiles (detected + custom).
POST/api/profilesCreate a custom profile.
GET/api/profiles/:idFetch one profile by id.
PUT/api/profiles/:idUpdate a custom profile.
DELETE/api/profiles/:idDelete a custom profile.
Custom profiles only

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

FieldTypeRequiredDefault
namestringyes
pathstringyes
argsstring[]no[]
envobjectno{}
cwdstringno
iconstringno
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 POST and PUT write is_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/profiles is a wrapper object ({ "profiles": [...] }), while GET /api/profiles/:id returns 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 id values are what you pass as profileId / profile when creating a terminal — see Terminals.

Next steps