> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sevalla.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> These are the docs for Sevalla, a platform for deploying applications, databases, static sites, object storage and load balancers. The dashboard is at https://app.sevalla.com.
> Bold text in steps is an exact dashboard label.
> To act on a Sevalla account, prefer the Sevalla MCP server (https://mcp.sevalla.com/mcp, see https://docs.sevalla.com/ai-agents/overview.md), then the Sevalla CLI (https://docs.sevalla.com/developer-tools/cli.md), then the REST API (https://api-docs.sevalla.com, OpenAPI spec at https://api.sevalla.com/v3/openapi.json).
> Every page index is at https://docs.sevalla.com/llms.txt.

# Deploy Flowise

> Run Flowise from its official Docker image with PostgreSQL, fixed encryption and sign-in secrets, then create a Claude flow and run it through Flowise's API with an API key.

Flowise runs on Sevalla as an application from its official Docker image, `flowiseai/flowise`: the web process serves the visual editor and the API that runs your flows, and a Sevalla PostgreSQL database keeps the accounts, flows, API keys and encrypted credentials, so the application needs no disk. Environment variables fix the encryption key and the sign-in secrets, so credentials and sessions survive every deployment, and each flow you call from other applications is protected by a Flowise API key.

## At a glance

| | |
| - | - |
| Source | The `flowiseai/flowise:3.1.4` Docker image |
| Start command | The image's own, `flowise start` |
| Port | `8080`, from the `PORT` environment variable that Sevalla sets (Flowise's own default is `3000`) |
| Processes | Web process |
| Services | PostgreSQL 18 over an internal connection |
| Disk | None. Add one only to keep [uploaded files](#keep-uploaded-files) |
| Health check | `GET /api/v1/ping` returns `pong` (readiness probe) |
| Size | **S1** (0.5 vCPU, 1 GB) |

### Environment variables

| Variable | Required | Available during | Secret | Value |
| - | - | - | - | - |
| `DATABASE_TYPE` | Yes | Runtime | No | `postgres` |
| `DATABASE_HOST` | Yes | Runtime | No | `DB_HOST` from the internal connection, renamed |
| `DATABASE_PORT` | Yes | Runtime | No | `DB_PORT` from the internal connection, renamed |
| `DATABASE_NAME` | Yes | Runtime | No | `DB_DATABASE` from the internal connection, renamed |
| `DATABASE_USER` | Yes | Runtime | No | `DB_USERNAME` from the internal connection, renamed |
| `DATABASE_PASSWORD` | Yes | Runtime | Yes | `DB_PASSWORD` from the internal connection, renamed |
| `FLOWISE_SECRETKEY_OVERWRITE` | Yes | Runtime | Yes | Generate with `openssl rand -base64 32`, and keep a copy: see [Keep the secrets](#keep-the-secrets) |
| `JWT_AUTH_TOKEN_SECRET` | Yes | Runtime | Yes | Generate with `openssl rand -base64 32` |
| `JWT_REFRESH_TOKEN_SECRET` | Yes | Runtime | Yes | Generate with `openssl rand -base64 32` |
| `EXPRESS_SESSION_SECRET` | Yes | Runtime | Yes | Generate with `openssl rand -base64 32` |
| `TOKEN_HASH_SECRET` | Yes | Runtime | Yes | Generate with `openssl rand -base64 32` |
| `APP_URL` | Yes | Runtime | No | The application's URL, for example `https://flowise-x7k2m.sevalla.app` |
| `PORT` | No | Runtime | No | Set by Sevalla to the web process port |

An application from a Docker image has no build, so every variable is a runtime variable. [Set the environment variables](#set-the-environment-variables) explains each one. Your Anthropic API key isn't an environment variable: Flowise stores it as an encrypted credential in PostgreSQL.

## Before you begin

* A Sevalla company with a payment method: Flowise needs the **S1** size or larger.
* OpenSSL, `curl` and `jq` on your computer, to generate the secrets and call Flowise's API.
* An API key from your model provider. This guide uses [Anthropic](https://console.anthropic.com/).

## Create the database

**1. Open the create form**

In the sidebar, click **Databases**, then click **Create database**.

**2. Choose PostgreSQL**

Click **PostgreSQL** and choose the newest version. This guide was tested with PostgreSQL 18.

**3. Name and place it**

Enter the **Display name** `flowise-db`, choose the **Data center** where Flowise will run, and choose the **Size**. This guide was tested on **DB1**.

**4. Create it**

Click **Create database** and wait for the status **Ready**.

Flowise's default database is a SQLite file in the container, which every deployment deletes. Flowise 3.1.4 also doesn't start on it in Docker: it stops with `TypeError: this.db.exec is not a function`.

## Create the application

**1. Choose the image**

In the sidebar, click **Applications**, then click **Create** > **Application**. Under **Source**, click **Docker image** and enter `flowiseai/flowise:3.1.4` in **Docker image**. Keep the **Registry credential** at **None (public image)**.

**2. Name, place and size it**

Enter the **Name** `flowise`, choose the database's **Data center**, and choose the **Size** **S1**.

**3. Create it without deploying**

Click **Create application**. The application opens with the status **Not deployed yet**. Note its domain under the name, for example `flowise-x7k2m.sevalla.app`: `APP_URL` needs it.

The tag pins one Flowise release: `3.1.4` is the current one. The image is a 1.5 GB download and runs Flowise as the unprivileged `node` user. Flowise migrates its database when a new version starts, so pin a version and [upgrade on purpose](#upgrade-flowise).

## Connect the database

Flowise reads its database settings from separate variables, not a connection URL. The internal connection adds the same values under other names; rename them as you add them.

**1. Open the database's networking**

In the sidebar, click **Databases**, then click `flowise-db`. Click the **Networking** tab.

**2. Add the connection**

Under **Private networking**, in **Connected applications**, click **Add internal connection**, and choose the `flowise` **Application**.

**3. Rename the variables**

Turn on **Add environment variables to the application**. Change the keys `DB_HOST` to `DATABASE_HOST`, `DB_PORT` to `DATABASE_PORT`, `DB_DATABASE` to `DATABASE_NAME`, `DB_USERNAME` to `DATABASE_USER` and `DB_PASSWORD` to `DATABASE_PASSWORD`. Click the trash icon next to `DB_URL`: Flowise doesn't read it.

**4. Save**

Click **Add internal connection**.

## Set the environment variables

Generate five secrets on your computer, one per run of this command, and store them in your password manager before you add them:

```bash theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
openssl rand -base64 32
```

On the application's **Environment variables** tab, click **Add environment variables**, paste these lines into the first key field, replace the secrets and the domain with yours, and click **Add environment variables**:

```bash .env theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
DATABASE_TYPE=postgres
FLOWISE_SECRETKEY_OVERWRITE=Q2hhbmdlIG1lOiBnZW5lcmF0ZSB5b3VyIG93biBrZXk=
JWT_AUTH_TOKEN_SECRET=b5Xq2Lr8Vt1Nw6Kc3Hy9Pd4Mf7Zs0Ga2Jj5Ue8Ri1Oo=
JWT_REFRESH_TOKEN_SECRET=Yt3Wm6Qa9Ec2Rv5Tb8Un1Ix4Oz7Pl0Sk3Dj6Fh9Gg2A=
EXPRESS_SESSION_SECRET=Hc8Nd1Me4Lf7Kg0Jh3Ii6Gj9Fk2El5Dm8Cn1Bo4Ap7Q=
TOKEN_HASH_SECRET=Zp5Yq8Xr1Ws4Vt7Uu0Tv3Sw6Rx9Qy2Pz5Oa8Nb1Mc4L=
APP_URL=https://flowise-x7k2m.sevalla.app
```

| Variable | Why Flowise needs it on Sevalla |
| - | - |
| `DATABASE_TYPE` | Stores everything in the PostgreSQL database from the internal connection instead of a SQLite file in the container. |
| `FLOWISE_SECRETKEY_OVERWRITE` | Encrypts the credentials you save in Flowise, such as your Anthropic API key. Without it, Flowise generates a key into `/home/node/.flowise`, a folder that the next deployment deletes. See [Keep the secrets](#keep-the-secrets). |
| `JWT_AUTH_TOKEN_SECRET`, `JWT_REFRESH_TOKEN_SECRET`, `TOKEN_HASH_SECRET` | Sign the tokens that keep you signed in, and encrypt the account and workspace IDs inside them. Without them, Flowise generates new ones into `/home/node/.flowise` at each start, and every deployment signs everyone out. |
| `EXPRESS_SESSION_SECRET` | Signs the session cookie. Flowise keeps the sessions in PostgreSQL; the secret must stay the same for them to stay valid. |
| `APP_URL` | The public URL Flowise builds links from. Because it starts with `https`, Flowise marks its sign-in cookies `Secure`: the image doesn't set `NODE_ENV=production`, which would do the same. |

You don't set `PORT`: Sevalla sets it to the web process port, `8080`, and Flowise listens on it on all interfaces. Flowise trusts the `X-Forwarded-For` header of every proxy by default, so it needs no setting for Cloudflare and Sevalla's proxy.

## Add a readiness probe

Flowise connects to PostgreSQL and runs its migrations before it answers; in the tests, it was ready 6 seconds after it started. A readiness probe keeps sending requests to the running version until the new one is ready.

**1. Open the web process**

Click the **Processes** tab, click **⋯** on the web process, then click **Update process**.

**2. Turn on the probe**

Under **Health checks**, turn on **Readiness probe**, enter the **Path** `/api/v1/ping`, the **Initial delay** `10` and the **Timeout** `5`. Keep the **Port** at `8080`.

**3. Save**

Click **Update process**.

## Deploy Flowise

Click the **Overview** tab, click **Deploy now**, then click **Deploy**. The deployment pulls the image and starts the web process; there's no build. In the tests, a deployment took between 35 seconds and 2.5 minutes, most of it pulling the image.

> [!WARNING]
>
> Until you create the first account, anyone who opens the application's domain can create it and take over the instance. Create it right after the first deployment.

**1. Open Flowise**

When the deployment is **Deployed**, click the domain under the application's name. Flowise shows **Setup Account**.

**2. Create the first account**

Enter the **Administrator Name**, the **Administrator Email** and a **Password** of at least 8 characters with a lowercase letter, an uppercase letter, a digit and a special character, repeat it in **Confirm Password**, then click **Sign Up**.

The first account owns the instance. Flowise's open source edition has one organization: after the first account exists, the sign-up endpoint answers `400` with `You can only have one organization`. Sign-in is required for the editor and for Flowise's management API.

## Verify the deployment

1. On the **Deployments** tab, the deployment's status is **Deployed**. With the API, [Get deployment](https://api-docs.sevalla.com/v3/applications/get-deployment) (`getDeploymentV3`) returns `"status": "success"`.
2. The application's [runtime logs](https://docs.sevalla.com/applications/logs.md) show `Flowise Server is listening at :8080`. [Get application runtime logs](https://api-docs.sevalla.com/v3/applications/get-application-runtime-logs) (`getApplicationRuntimeLogsV3`) finds it with `search=listening`.
3. The ping endpoint answers:

   ```bash theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
   curl -s https://flowise-x7k2m.sevalla.app/api/v1/ping
   ```

   ```text theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
   pong
   ```

The runtime logs also show `Error during initDatabase` for the ReAct agent and AWS Bedrock nodes at each start. Flowise 3.1.4 can't load those nodes and leaves them out of the editor; everything else works.

## Create a flow with Claude

This flow answers customer questions about a shop with `claude-haiku-5-5`, Anthropic's fastest and cheapest current model. You create it with Flowise's own API, which also stores your Anthropic key as an encrypted credential and protects the flow with a Flowise API key. Set these variables first:

```bash theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
FLOWISE_URL=https://flowise-x7k2m.sevalla.app
ADMIN_EMAIL=admin@example.com
ADMIN_PASSWORD='<the password of the first account>'
ANTHROPIC_API_KEY='<your Anthropic API key>'
```

Save the flow as `shop-assistant.json`. It connects an Anthropic chat model and a prompt template to an LLM chain:

```json shop-assistant.json theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
{
  "nodes": [
    {
      "id": "chatAnthropic_0",
      "type": "customNode",
      "position": { "x": 0, "y": 0 },
      "data": {
        "id": "chatAnthropic_0", "name": "chatAnthropic", "label": "ChatAnthropic", "category": "Chat Models",
        "credential": "", "inputParams": [], "inputAnchors": [], "outputAnchors": [],
        "inputs": { "modelName": "claude-haiku-5-5", "adaptiveThinking": true, "thinkingEffort": "low", "maxTokensToSample": 400, "streaming": true }
      }
    },
    {
      "id": "promptTemplate_0",
      "type": "customNode",
      "position": { "x": 0, "y": 400 },
      "data": {
        "id": "promptTemplate_0", "name": "promptTemplate", "label": "Prompt Template", "category": "Prompts",
        "inputParams": [], "inputAnchors": [], "outputAnchors": [],
        "inputs": { "template": "You answer questions from customers of Acme Coffee Supply in one or two sentences.\nOrders ship Monday to Friday. Shipping to Canada costs 19.90 EUR and takes 6 to 9 business days.\nQuestion: {question}" }
      }
    },
    {
      "id": "llmChain_0",
      "type": "customNode",
      "position": { "x": 450, "y": 200 },
      "data": {
        "id": "llmChain_0", "name": "llmChain", "label": "LLM Chain", "category": "Chains",
        "inputParams": [], "inputAnchors": [], "outputAnchors": [],
        "inputs": { "model": "{{chatAnthropic_0.data.instance}}", "prompt": "{{promptTemplate_0.data.instance}}" },
        "outputs": { "output": "llmChain" }
      }
    }
  ],
  "edges": [
    { "id": "chatAnthropic_0-llmChain_0", "source": "chatAnthropic_0", "target": "llmChain_0" },
    { "id": "promptTemplate_0-llmChain_0", "source": "promptTemplate_0", "target": "llmChain_0" }
  ]
}
```

**1. Sign in**

`POST /api/v1/auth/login` stores the session cookies in `flowise.cookies`. Calls that use the cookies also need the header `x-request-from: internal`, which Flowise's editor sends; without it, Flowise answers `401` with `Unauthorized Access`.

```bash theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
curl -s -c flowise.cookies -X POST "$FLOWISE_URL/api/v1/auth/login" -H "Content-Type: application/json" \
  -d "$(jq -n --arg e "$ADMIN_EMAIL" --arg p "$ADMIN_PASSWORD" '{email:$e, password:$p}')" \
  | jq -r .email
SESSION=(-b flowise.cookies -H "x-request-from: internal" -H "Content-Type: application/json")
```

```text theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
admin@example.com
```

**2. Create an API key**

The key is what other applications send to run the flow. Flowise answers with all keys, so pick the new one by its name:

```bash theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
curl -s "${SESSION[@]}" -X POST "$FLOWISE_URL/api/v1/apikey" -d '{"keyName":"storefront","permissions":["chatflows:view"]}' > apikeys.json
FLOWISE_KEY_ID=$(jq -r 'map(select(.keyName == "storefront")) | max_by(.updatedDate) | .id' apikeys.json)
FLOWISE_API_KEY=$(jq -r 'map(select(.keyName == "storefront")) | max_by(.updatedDate) | .apiKey' apikeys.json)
rm apikeys.json
```

Store `FLOWISE_API_KEY` in the calling application's [environment variables](https://docs.sevalla.com/applications/environment-variables.md). In the editor, the keys are under **API Keys**.

**3. Store the Anthropic key**

Flowise encrypts the credential with `FLOWISE_SECRETKEY_OVERWRITE`:

```bash theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
CREDENTIAL_ID=$(curl -s "${SESSION[@]}" -X POST "$FLOWISE_URL/api/v1/credentials" \
  -d "$(jq -n --arg k "$ANTHROPIC_API_KEY" '{name:"Anthropic", credentialName:"anthropicApi", plainDataObj:{anthropicApiKey:$k}}')" \
  | jq -r .id)
```

**4. Create the flow**

The request sets the credential in the model node and assigns the API key to the flow:

```bash theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
FLOW_ID=$(curl -s "${SESSION[@]}" -X POST "$FLOWISE_URL/api/v1/chatflows" \
  -d "$(jq -n --arg cred "$CREDENTIAL_ID" --arg key "$FLOWISE_KEY_ID" --slurpfile flow shop-assistant.json \
    '{name:"Shop assistant", type:"CHATFLOW", apikeyid:$key, flowData:($flow[0] | .nodes[0].data.credential = $cred | tojson)}')" \
  | jq -r .id)
```

The flow appears under **Chatflows** as **Shop assistant**.

`adaptiveThinking` and `thinkingEffort` are there because of `claude-haiku-5-5`: Flowise 3.1.4's Anthropic node sends `temperature` unless thinking is on, and the model rejects it with `` `temperature` is deprecated for this model. `` With adaptive thinking at the `low` effort, the model used no thinking tokens in the tests: a question cost 102 input and 46 output tokens.

### The flow in the editor

Flowise's editor shows this flow's three nodes, but not their settings or connections: the JSON leaves out the field definitions that the editor adds when you build a flow there. Change the flow through the API ([Flowise's API reference](https://docs.flowiseai.com/api-reference/chatflows) has the update operation), or build flows in the editor instead. In the editor, the Anthropic node's **Model Name** list comes from a model list that Flowise downloads from its GitHub repository: today its newest models are `claude-opus-4-7` and `claude-haiku-4-5`, and the node shows **Adaptive Thinking** only for `claude-opus-4-7`, `claude-opus-4-6` and `claude-sonnet-4-6`. In the tests, the node ran `claude-haiku-4-5` with its default temperature.

## Run the flow through the API

The prediction endpoint runs a flow by its ID, with the flow's API key in the `Authorization` header:

```bash theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
curl -s -X POST "https://flowise-x7k2m.sevalla.app/api/v1/prediction/$FLOW_ID" \
  -H "Authorization: Bearer $FLOWISE_API_KEY" -H "Content-Type: application/json" \
  -d '{"question":"How much is shipping to Canada, and how long does it take?"}' | jq -r .text
```

```text theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
Shipping to Canada costs 19.90 EUR and takes 6 to 9 business days. Orders ship Monday through Friday.
```

The model writes the answer in its own words, so yours can differ. The run took about 1.3 seconds in the tests. Without the header, the endpoint answers `500` with `Error: predictionsServices.buildChatflow - Unauthorized`.

> [!WARNING]
>
> A flow without an API key runs for anyone who knows its ID, and every run spends from your Anthropic account. Assign an API key to every flow you call from outside, as the request in [Create a flow with Claude](#create-a-flow-with-claude) does, and set a spending limit in your model provider's console.

Add `"streaming": true` to the body to receive the answer as Server-Sent Events (`Content-Type: text/event-stream`, `Cache-Control: no-cache`): a `start` event, one `token` event per piece of text, then `metadata` and `end`. Through Cloudflare and Sevalla's proxy, the first token of a two-sentence answer arrived after 1.4 seconds and the last after 1.5 seconds, without buffering.

```bash theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
curl -sN -X POST "https://flowise-x7k2m.sevalla.app/api/v1/prediction/$FLOW_ID" \
  -H "Authorization: Bearer $FLOWISE_API_KEY" -H "Content-Type: application/json" \
  -d '{"question":"Do you ship on Saturdays?","streaming":true}'
```

## Keep the secrets

`FLOWISE_SECRETKEY_OVERWRITE` and the four sign-in secrets must stay the same for the life of the instance. In the tests, sessions and credentials survived every deployment while they stayed the same.

> [!WARNING]
>
> If you change or delete `FLOWISE_SECRETKEY_OVERWRITE`, Flowise can no longer decrypt the credentials you saved: flows that use them fail with `Error: predictionsServices.buildChatflow - Error: Anthropic API key not found`. Keep a copy of the key outside Sevalla, so deleting the variable or the application doesn't lose it.

Set the variable back to the original key and deploy again: the credentials are readable again. A changed `JWT_AUTH_TOKEN_SECRET` only signs everyone out: requests with the old session answer `401` with `{"message":"Invalid or Missing token"}` until you sign in again.

## Keep uploaded files

Flows, credentials, API keys and chat history are in PostgreSQL. Files that flows store, such as uploads in a chat or documents in a document store, go to `/home/node/.flowise/storage`, which every deployment deletes. To keep them, add a disk:

**1. Create the disk**

On the application's **Disks** tab, click **Create disk**. Pick the web process, enter the **Path** `/home/node/.flowise`, pick the **Size** `10 GB`, and click **Create disk**.

**2. Deploy**

Deploy the application. Flowise writes to the disk from this deployment on.

In the tests, a file in `/home/node/.flowise/storage` was still there after the next deployment. A process with a disk runs 1 instance and stops before the new version starts ([Persistent storage](https://docs.sevalla.com/applications/disks.md)): during each deployment, Flowise answered `503` for about 30 seconds.

## Upgrade Flowise

1. Read the release notes of every version between yours and the new one on [Flowise's GitHub releases](https://github.com/FlowiseAI/Flowise/releases).
2. Back up `flowise-db`: on its **Backups** tab, create a manual backup. See [Backups](https://docs.sevalla.com/databases/backups.md).
3. On the application's **Settings** tab, in the **Source** section, click **Update source**, change the tag in **Docker image**, and click **Update source**.
4. Deploy. Flowise migrates the database when the new version starts.

To go back, restore the backup and set the previous tag.

## Add a custom domain

To serve Flowise from your own domain, such as `flows.example.com`, add it on the application's **Domains** tab and create the DNS records Sevalla shows; the web process must be larger than **H1**, which **S1** is. Then change `APP_URL` to `https://flows.example.com` and deploy. See [Custom domains](https://docs.sevalla.com/domains/overview.md).

## Troubleshoot

| Symptom | Cause | Fix |
| - | - | - |
| The log shows `TypeError: this.db.exec is not a function` and Flowise doesn't start | `DATABASE_TYPE` isn't set, so Flowise uses SQLite | [Connect PostgreSQL](#connect-the-database) and set `DATABASE_TYPE=postgres` |
| A run returns `500` with `` `temperature` is deprecated for this model. `` | The flow uses `claude-haiku-5-5` without adaptive thinking | Set `adaptiveThinking` to `true` in the model node, as in [Create a flow with Claude](#create-a-flow-with-claude) |
| A run returns `500` with `Error: predictionsServices.buildChatflow - Unauthorized` | The flow has an API key and the request doesn't send it | Send `Authorization: Bearer` with the flow's API key |
| A run returns `500` with `Error: predictionsServices.buildChatflow - Error: Anthropic API key not found` | `FLOWISE_SECRETKEY_OVERWRITE` changed, so Flowise can't decrypt the credential | Set it back to the original key and deploy. See [Keep the secrets](#keep-the-secrets) |
| Everyone is signed out after a deployment, and requests answer `{"message":"Invalid or Missing token"}` | `JWT_AUTH_TOKEN_SECRET`, `JWT_REFRESH_TOKEN_SECRET` or `TOKEN_HASH_SECRET` isn't set or changed | Set them to fixed values and deploy |
| An API call with the session cookie answers `401` with `Unauthorized Access` | The request doesn't send `x-request-from: internal` | Add the header, or use an API key |
| Sign-up answers `400` with `You can only have one organization` | The first account already exists | Sign in with the first account |

## Deploy with the API

These calls create the same deployment without the dashboard: the database, the application, the variables, the readiness probe, the first deployment and the first account. They need:

* An [API key](https://docs.sevalla.com/developer-tools/api-keys.md) that can create applications and databases, in `SEVALLA_API_KEY`.
* `curl`, `jq` and `openssl`.

The application comes from a public Docker image, so no Git provider needs to be connected.

**1. Choose the location and sizes**

[List clusters](https://api-docs.sevalla.com/v3/resources/list-clusters) (`listClustersV3`), [List process resource types](https://api-docs.sevalla.com/v3/resources/list-process-resource-types) (`listProcessResourceTypesV3`) and [List database resource types](https://api-docs.sevalla.com/v3/resources/list-database-resource-types) (`listDatabaseResourceTypesV3`). Pick the location by its region ID, here Frankfurt:

```bash theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
API=https://api.sevalla.com/v3
AUTH="Authorization: Bearer $SEVALLA_API_KEY"
CLUSTER_ID=$(curl -s "$API/resources/clusters" -H "$AUTH" | jq -r '.[] | select(.location == "eu-frankfurt-1") | .id')
S1=$(curl -s "$API/resources/process-resource-types" -H "$AUTH" | jq -r '.[] | select(.name == "s1") | .id')
DB1=$(curl -s "$API/resources/database-resource-types" -H "$AUTH" | jq -r '.[] | select(.name == "db1") | .id')
```

CLI: `sevalla resources clusters`, `sevalla resources process-types` and `sevalla resources db-types`. MCP: `get_platform_options`.

**2. Create the database**

[Create database](https://api-docs.sevalla.com/v3/databases/create-database) (`createDatabaseV3`). The API doesn't return the password later, so generate it here:

```bash theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
DB_PASSWORD=$(openssl rand -hex 16)
DB_ID=$(curl -s -X POST "$API/databases" -H "$AUTH" -H "Content-Type: application/json" \
  -d "$(jq -n --arg c "$CLUSTER_ID" --arg r "$DB1" --arg p "$DB_PASSWORD" \
    '{display_name:"flowise-db", type:"postgresql", version:"18", cluster_id:$c, resource_type_id:$r, db_name:"flowise", db_user:"flowise", db_password:$p}')" \
  | jq -r .id)
```

CLI: `sevalla databases create --name flowise-db --type postgresql --db-version 18 --cluster $CLUSTER_ID --resource-type $DB1 --db-name flowise --db-user flowise --db-password $DB_PASSWORD`. MCP: `sevalla_api_create` with `createDatabaseV3` and the same body (`create_database` generates a password it doesn't return, and Flowise needs it).

**3. Wait for the database**

[Get database](https://api-docs.sevalla.com/v3/databases/get-database) (`getDatabaseV3`) until `status` is `ready`, then read the internal hostname:

```bash theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
for i in $(seq 1 60); do [ "$(curl -s "$API/databases/$DB_ID" -H "$AUTH" | jq -r .status)" = ready ] && break; sleep 10; done
DB_HOST=$(curl -s "$API/databases/$DB_ID" -H "$AUTH" | jq -r .internal_hostname)
```

CLI: `sevalla databases get $DB_ID`. MCP: `get_database`.

**4. Create the application**

[Create application](https://api-docs.sevalla.com/v3/applications/create-application) (`createApplicationV3`) with the Docker image source. It doesn't start a deployment:

```bash theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
APP_ID=$(curl -s -X POST "$API/applications" -H "$AUTH" -H "Content-Type: application/json" \
  -d "$(jq -n --arg c "$CLUSTER_ID" '{display_name:"flowise", cluster_id:$c, source:"dockerImage", docker_image:"flowiseai/flowise:3.1.4"}')" \
  | jq -r .id)
for i in $(seq 1 30); do APP_HOST=$(curl -s "$API/applications/$APP_ID/domains" -H "$AUTH" | jq -r '.data[] | select(.is_primary) | .name'); [ -n "$APP_HOST" ] && break; sleep 2; done
WEB_ID=$(curl -s "$API/applications/$APP_ID/processes" -H "$AUTH" | jq -r '.data[] | select(.type == "web") | .id')
```

The last two calls are [List application domains](https://api-docs.sevalla.com/v3/applications/list-application-domains) (`listApplicationDomainsV3`) and [List processes](https://api-docs.sevalla.com/v3/applications/list-processes) (`listProcessesV3`). CLI: `sevalla apps create --name flowise --cluster $CLUSTER_ID --source dockerImage --docker-image flowiseai/flowise:3.1.4`. MCP: `create_application` with `deploy: false`, then `get_application`.

**5. Size the web process and add the readiness probe**

[Update process](https://api-docs.sevalla.com/v3/applications/update-process) (`updateProcessV3`). The API creates the web process at **S1** already; send the size anyway if you change it. Always send `timeoutSeconds`: without it, the probe gets 120 seconds instead of the dashboard's 1:

```bash theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
curl -s -X PATCH "$API/applications/$APP_ID/processes/$WEB_ID" -H "$AUTH" -H "Content-Type: application/json" \
  -d "$(jq -n --arg r "$S1" '{resource_type_id:$r, readiness_probe:{httpGet:{path:"/api/v1/ping", port:8080}, initialDelaySeconds:10, periodSeconds:5, timeoutSeconds:5, successThreshold:1, failureThreshold:3}}')" \
  | jq -r .resource_type_name
```

```text theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
s1
```

CLI: `sevalla apps processes update $WEB_ID --app-id $APP_ID --resource-type $S1` (the CLI can't set a probe). MCP: `sevalla_api_update` with `updateProcessV3` and the same body.

**6. Connect the database**

[Create internal connection](https://api-docs.sevalla.com/v3/applications/create-internal-connection) (`createApplicationInternalConnectionV3`). Unlike the dashboard, it adds no variables:

```bash theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
curl -s -X POST "$API/applications/$APP_ID/internal-connections" -H "$AUTH" -H "Content-Type: application/json" \
  -d "$(jq -n --arg t "$DB_ID" '{target_id:$t, target_type:"database"}')"
```

CLI: `sevalla apps internal-connections create $APP_ID --target-id $DB_ID --target-type database`. MCP: `sevalla_api_create` with `createApplicationInternalConnectionV3`.

**7. Add the environment variables**

[Create environment variable](https://api-docs.sevalla.com/v3/applications/create-environment-variable) (`createEnvironmentVariableV3`), once per variable. Store `FLOWISE_SECRETKEY_OVERWRITE` somewhere safe before you send it:

```bash theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
add_var() {
  curl -s -X POST "$API/applications/$APP_ID/env-vars" -H "$AUTH" -H "Content-Type: application/json" \
    -d "$(jq -n --arg k "$1" --arg v "$2" '{key:$k, value:$v, is_runtime:true, is_buildtime:false}')" | jq -r .key
}
add_var DATABASE_TYPE postgres
add_var DATABASE_HOST "$DB_HOST"
add_var DATABASE_PORT 5432
add_var DATABASE_NAME flowise
add_var DATABASE_USER flowise
add_var DATABASE_PASSWORD "$DB_PASSWORD"
FLOWISE_SECRETKEY_OVERWRITE=$(openssl rand -base64 32)
add_var FLOWISE_SECRETKEY_OVERWRITE "$FLOWISE_SECRETKEY_OVERWRITE"
for name in JWT_AUTH_TOKEN_SECRET JWT_REFRESH_TOKEN_SECRET EXPRESS_SESSION_SECRET TOKEN_HASH_SECRET; do
  add_var "$name" "$(openssl rand -base64 32)"
done
add_var APP_URL "https://$APP_HOST"
```

Each call prints the key it added. CLI: `sevalla apps env-vars create $APP_ID --key DATABASE_TYPE --value postgres`, once per variable; the CLI makes each variable available during runtime and build, which makes no difference for an image. MCP: `set_environment_variables` with all of them in `variables`.

**8. Deploy**

[Trigger deployment](https://api-docs.sevalla.com/v3/applications/trigger-deployment) (`triggerDeploymentV3`):

```bash theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
DEPLOYMENT_ID=$(curl -s -X POST "$API/applications/$APP_ID/deployments" -H "$AUTH" -H "Content-Type: application/json" -d '{}' | jq -r .id)
```

CLI: `sevalla apps deployments trigger $APP_ID`. MCP: `trigger_deployment`.

**9. Wait for the deployment**

[Get deployment](https://api-docs.sevalla.com/v3/applications/get-deployment) (`getDeploymentV3`) until `status` is final (`success`, `failed`, `cancelled` or `skipped`), for up to 30 minutes; [Get application deployment logs](https://api-docs.sevalla.com/v3/applications/get-application-deployment-logs) (`getApplicationDeploymentLogsV3`) with `?limit=5000` shows why one failed:

```bash theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
for i in $(seq 1 120); do
  STATUS=$(curl -s "https://api.sevalla.com/v3/applications/$APP_ID/deployments/$DEPLOYMENT_ID" \
    -H "Authorization: Bearer $SEVALLA_API_KEY" | jq -r '.status // empty')
  case $STATUS in success|failed|cancelled|skipped) break ;; esac
  sleep 15
done
echo "$STATUS"
```

```text theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
success
```

CLI: `sevalla apps deployments get $DEPLOYMENT_ID --app-id $APP_ID` and `sevalla apps deployments logs $DEPLOYMENT_ID --app-id $APP_ID`. MCP: `get_deployment` and `get_deployment_logs`.

**10. Create the first account**

Flowise's sign-up endpoint creates the first account, the same one as **Setup Account**. Do it right after the deployment. The password needs a lowercase letter, an uppercase letter, a digit and a special character; keep it:

```bash theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
FLOWISE_URL="https://$APP_HOST"
ADMIN_EMAIL=admin@example.com
ADMIN_PASSWORD="Fw-$(openssl rand -hex 12)"
curl -s -w "\n" "$FLOWISE_URL/api/v1/ping"
curl -s -X POST "$FLOWISE_URL/api/v1/account/register" -H "Content-Type: application/json" \
  -d "$(jq -n --arg e "$ADMIN_EMAIL" --arg p "$ADMIN_PASSWORD" '{user:{name:"Admin", email:$e, credential:$p}}')" \
  | jq -r .user.email
```

```text theme={"theme":{"light":"github-dark-default","dark":"github-dark-default"}}
pong
admin@example.com
```

CLI and MCP: not available; this is Flowise's API.

Then set `ANTHROPIC_API_KEY` and run the steps in [Create a flow with Claude](#create-a-flow-with-claude) and [Run the flow through the API](#run-the-flow-through-the-api) with these variables.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.