# Manage FlowStreams with the Flow API

> Sign in, list, create, import, export, pause, restart and remove FlowStreams with the JSON API at /fapi/, read the statistics and the variables, and call a stream from outside with its notify address or its own proxy path.

Framework: flow
Product: Flow (flow@11.1)
Language: en
Content-SHA256: 1ca332525e645680edb0d12f3c3453b31624fe152137539464bca8173d80729b
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: 
Review: not-recorded

Everything the editor does goes through one JSON endpoint: `POST /fapi/` with the body `{ "schema": "<name>", "data": { ... } }` (the Total.js API routes, see [API routes](/en/total5/api-routes/)). The address `/fapi/` comes from the line `$api : /fapi/` of the `config` file. Every call except the sign-in needs the session cookie; without it the answer is `401: Unauthorized`.

These calls were also tried against a local Flow 11.1 (Node.js 24 and `total5@0.0.19`) while this page was written.

## Sign in

`Auth|login` takes `login` and `password` and answers `{"success":true}` with the session cookie. A wrong pair answers `Invalid credentials`.

```bash
curl -c cookie.txt -X POST http://localhost:8000/fapi/ \
  -H 'content-type: application/json' \
  -d '{"schema":"Auth|login","data":{"login":"<your login>","password":"<your password>"}}'
```

The next calls use `-b cookie.txt`.

## The calls

| `schema` | `data` | What it does |
|---|---|---|
| `Streams` | none | the list of FlowStreams with `id`, `name`, `group`, `author`, `version`, `proxypath`, `size` and the live `stats` of the running ones |
| `Streams\|save` | `name`, and optionally `author`, `version`, `icon`, `color`, `group`, `url`, `reference`, `readme`, `memory`, `cloning`, `proxypath`, `proxytimeout` | **creates** a stream when `id` is missing (the permission *create* is checked), otherwise updates the stream with that `id` and restarts it |
| `Streams\|read` | `id` | the properties of one stream |
| `Streams\|raw` | `id` | the whole stream object, with its design |
| `Streams\|export` | `id` | the stream as JSON text in `value`, without the internal fields (`unixsocket`, `env`, `import`, `worker`, `asfiles`) |
| `Streams\|import` | `data` (the JSON text) | creates a **new** stream from an export (up to 10 MB), with a new `id`; a repeated `proxypath` is replaced with a random one; answers `{"success":true,"value":"<id>"}` |
| `Streams\|pause` | `id`, `is` (`true` or `false`) | pauses or resumes a running stream |
| `Streams\|restart` | `id` | restarts the stream |
| `Streams\|remove` | `id` | removes the stream and its folder (the permission *remove* is checked) |
| `Streams\|stats` | none | the totals of the installation: versions of Node.js, Total.js and Flow, messages, pending, memory and connections |
| `Variables\|read` / `Variables\|save` | `id` (optional), `data` | the variables of one stream, or the **global** variables when `id` is empty; saving pushes them to the running streams |
| `Console\|read` / `Console\|clear` | none | the console of the application |
| `CDN\|clear` | none | clears the cache of the downloaded user-interface components |
| `Settings\|read` / `Settings\|save` | the settings (see [settings and files](/en/flow/settings-and-files/)) | only for the super administrator |

## Create a stream and run it

Create it, then import a design built in the editor (an exported JSON file) to start it:

```bash
curl -b cookie.txt -X POST http://localhost:8000/fapi/ \
  -H 'content-type: application/json' \
  -d '{"schema":"Streams|save","data":{"name":"Demo","author":"Me"}}'
```

A stream exported from the editor carries its `design` (the boxes and their connections), its `components` (the source of each one) and its `variables`.

## Rules of `proxypath`

A stream can publish HTTP routes under a path of its own. Flow adds the slashes (`demo` becomes `/demo/`), rejects the paths that belong to Flow itself (`/`, `/cdn/`, `/fapi/`, `/private/`, `/flows/`, `/designer/`, `/parts/`, `/forms/`, `/css/`, `/js/`, `/fonts/`, `/panels/`) with `Proxy endpoint contains reserved path`, and rejects a path that another stream already uses. `proxytimeout` is the time in seconds to wait for the answer of the stream (the default is `120`).

## Calls from outside

| Route | Use |
|---|---|
| `GET` or `POST /notify/{id}/` | sends a notification to the stream with that id (the POST body is limited to 1 MB); the components of the stream decide what to do with it. Answers `{"success":true}` |
| `+SOCKET /{id}/` | the WebSocket of the editor for that stream (it needs the session) |
| `GET /private/?token=<token>` | lists the files of the folder `private/` when the token equals the `token` of the settings; ten wrong tokens block an address for 15 minutes |
| `+POST /update/` | updates the application from a `.bundle` file; only for the bundled version |

Keep the `token` secret, send these calls over HTTPS and put Flow behind a reverse proxy when it is reachable from the Internet.
