Dify Console API
Use this to drive self-hosted Dify over HTTP. Pair with Dify troubleshooting when a call fails. Prefix lookup: Dify API catalog.
Login
Password is Base64, not RSA. Plaintext → 401 Invalid encrypted data.
PW=$(python3 -c "import base64; print(base64.b64encode(b'PASSWORD').decode())")
curl -c /tmp/dify-cookies.txt -X POST "$DIFY/console/api/login" \
-H 'Content-Type: application/json' \
-d "{\"email\":\"USER@email\",\"password\":\"$PW\",\"language\":\"zh-Hans\",\"remember_me\":true}"
CSRF=$(awk '$6=="csrf_token"{print $7}' /tmp/dify-cookies.txt)
Every later Console call (GET included): -b /tmp/dify-cookies.txt -H "X-CSRF-Token: $CSRF". Cookie without CSRF → 401 CSRF token is missing or invalid. 1.17 validates CSRF on reads, not only POST/PUT/DELETE. Access token cookies expire ~1h; login again. POST /refresh-token if you still have the refresh cookie.
Sanity: GET /console/api/setup (finished = admin exists), GET /console/api/account/profile, GET /console/api/features, GET /console/api/system-features, GET /console/api/app-dsl-version. Skip GET /version unless you know its query shape — 1.17 returns 422 without it. GET / unauthenticated → 307 /signin is normal, not a broken install.
First-time box: open /install only if setup is not_started. Do not POST /setup if already finished.
Conventions
- Prefix
/console/api. Default compose nginx is :80.
- JSON in/out. Files: multipart (
POST /files/upload; GET on the same path is metadata). Support types: GET /files/support-type. Console uploads are not valid on /v1.
- Prefer this API over clicking the UI. Browser only for
/install, OAuth, captcha.
- Never write passwords or
SECRET_KEY into skills/git. Changing SECRET_KEY after boot logs everyone out and breaks signed file URLs.
- Keep
DEPLOYMENT_EDITION=COMMUNITY.
GET /apps is classic apps (workflow / advanced-chat / agent-chat / …). Agent Studio roster is GET /agent and will not show up in /apps. Do not report “the agent app was deleted”.
Endpoint map
| Area |
Routes |
Next skill |
| Apps |
GET/POST /apps, GET/PUT/DELETE /apps/{id}, POST /apps/{id}/copy, GET /apps/{id}/export, POST /apps/imports |
Dify apps and workflows — never delete-and-reimport to ship a version: imports mints a new app_id and keys/site/logs/triggers on the old id die |
| Canvas |
GET/POST /apps/{id}/workflows/draft, POST .../publish, POST .../draft/run, human-input, comments |
Dify apps and workflows |
| Datasets |
GET/POST /datasets, /datasets/{id}/documents, segments, metadata |
Dify knowledge bases |
| RAG pipeline |
/rag/pipelines, /rag/pipeline/dataset |
Dify workspace extras |
| Models |
/workspaces/current/model-providers, .../default-model, .../models |
Dify model providers |
| Tools |
/workspaces/current/tool-providers |
Dify agents and tools |
| Agent Studio |
/agent, /agent/{id}/* |
Dify workspace extras |
| Workspace Skills / snippets |
/workspaces/current/skills, /workspaces/current/customized-snippets |
Dify workspace extras |
| MCP / endpoints |
/apps/{id}/server, /workspaces/current/endpoints |
Dify workspace extras |
| Plugins |
/workspaces/current/plugin/list, install/*, upload/pkg, tasks |
Dify plugin install |
| Files |
POST /files/upload, GET /files/{id}/preview |
Dify service API |
| Keys |
POST /apps/{id}/api-keys, POST /apps/{id}/api-enable |
Dify service API |
| Members / tags |
/workspaces/current/members, /tags |
Dify workspace extras |
| Logs / stats / annotations |
/apps/{id}/chat-conversations, /workflow-app-logs, /workflow-runs, /statistics/*, /workflow/statistics/*, /annotations |
Dify workspace extras |
| Agent Studio runtime / sandbox |
/agent/{id}/chat-messages, /agent/{id}/logs, /agent/{id}/sandbox/* |
Dify workspace extras |
| Dataset hit-test |
POST /datasets/{id}/hit-testing |
Dify knowledge bases |
| Triggers |
/apps/{id}/triggers, /apps/{id}/trigger-enable |
Dify apps and workflows |
After reboot
Nested/cloud VMs often need manual dockerd, then docker compose up -d from the Dify docker/ dir. Do not compose down -v. See Dify backup and upgrade.
1---2name: dify-console-api3description: Use this when logging into or driving self-hosted Dify via Console API (CSRF, apps, workflows, plugins, datasets).4---5# Dify Console API67Use this to drive self-hosted Dify over HTTP. Pair with [Dify troubleshooting](sand-workflow:dify-troubleshooting) when a call fails. Prefix lookup: [Dify API catalog](sand-workflow:dify-api-catalog).89## Login10Password is **Base64**, not RSA. Plaintext → `401 Invalid encrypted data`.1112```bash13PW=$(python3 -c "import base64; print(base64.b64encode(b'PASSWORD').decode())")14curl -c /tmp/dify-cookies.txt -X POST "$DIFY/console/api/login" \15 -H 'Content-Type: application/json' \16 -d "{\"email\":\"USER@email\",\"password\":\"$PW\",\"language\":\"zh-Hans\",\"remember_me\":true}"17CSRF=$(awk '$6=="csrf_token"{print $7}' /tmp/dify-cookies.txt)18```1920Every later Console call (GET included): `-b /tmp/dify-cookies.txt -H "X-CSRF-Token: $CSRF"`. Cookie without CSRF → `401 CSRF token is missing or invalid`. 1.17 validates CSRF on **reads**, not only POST/PUT/DELETE. Access token cookies expire ~1h; login again. `POST /refresh-token` if you still have the refresh cookie.2122Sanity: `GET /console/api/setup` (`finished` = admin exists), `GET /console/api/account/profile`, `GET /console/api/features`, `GET /console/api/system-features`, `GET /console/api/app-dsl-version`. Skip `GET /version` unless you know its `query` shape — 1.17 returns 422 without it. `GET /` unauthenticated → **307** `/signin` is normal, not a broken install.2324First-time box: open `/install` only if setup is `not_started`. Do not POST `/setup` if already finished.2526## Conventions27- Prefix `/console/api`. Default compose nginx is `:80`.28- JSON in/out. Files: multipart (`POST /files/upload`; GET on the same path is metadata). Support types: `GET /files/support-type`. Console uploads are **not** valid on `/v1`.29- Prefer this API over clicking the UI. Browser only for `/install`, OAuth, captcha.30- Never write passwords or `SECRET_KEY` into skills/git. Changing `SECRET_KEY` after boot logs everyone out and breaks signed file URLs.31- Keep `DEPLOYMENT_EDITION=COMMUNITY`.32- `GET /apps` is classic apps (`workflow` / `advanced-chat` / `agent-chat` / …). Agent Studio roster is `GET /agent` and will not show up in `/apps`. Do not report “the agent app was deleted”.3334## Endpoint map35| Area | Routes | Next skill |36|---|---|---|37| Apps | `GET/POST /apps`, `GET/PUT/DELETE /apps/{id}`, `POST /apps/{id}/copy`, `GET /apps/{id}/export`, `POST /apps/imports` | Dify apps and workflows — **never** delete-and-reimport to ship a version: `imports` mints a new `app_id` and keys/site/logs/triggers on the old id die |38| Canvas | `GET/POST /apps/{id}/workflows/draft`, `POST .../publish`, `POST .../draft/run`, human-input, comments | Dify apps and workflows |39| Datasets | `GET/POST /datasets`, `/datasets/{id}/documents`, segments, metadata | Dify knowledge bases |40| RAG pipeline | `/rag/pipelines`, `/rag/pipeline/dataset` | Dify workspace extras |41| Models | `/workspaces/current/model-providers`, `.../default-model`, `.../models` | Dify model providers |42| Tools | `/workspaces/current/tool-providers` | Dify agents and tools |43| Agent Studio | `/agent`, `/agent/{id}/*` | Dify workspace extras |44| Workspace Skills / snippets | `/workspaces/current/skills`, `/workspaces/current/customized-snippets` | Dify workspace extras |45| MCP / endpoints | `/apps/{id}/server`, `/workspaces/current/endpoints` | Dify workspace extras |46| Plugins | `/workspaces/current/plugin/list`, `install/*`, `upload/pkg`, `tasks` | Dify plugin install |47| Files | `POST /files/upload`, `GET /files/{id}/preview` | Dify service API |48| Keys | `POST /apps/{id}/api-keys`, `POST /apps/{id}/api-enable` | Dify service API |49| Members / tags | `/workspaces/current/members`, `/tags` | Dify workspace extras |50| Logs / stats / annotations | `/apps/{id}/chat-conversations`, `/workflow-app-logs`, `/workflow-runs`, `/statistics/*`, `/workflow/statistics/*`, `/annotations` | Dify workspace extras |51| Agent Studio runtime / sandbox | `/agent/{id}/chat-messages`, `/agent/{id}/logs`, `/agent/{id}/sandbox/*` | Dify workspace extras |52| Dataset hit-test | `POST /datasets/{id}/hit-testing` | Dify knowledge bases |53| Triggers | `/apps/{id}/triggers`, `/apps/{id}/trigger-enable` | Dify apps and workflows |5455## After reboot56Nested/cloud VMs often need **manual `dockerd`**, then `docker compose up -d` from the Dify `docker/` dir. Do not `compose down -v`. See Dify backup and upgrade.