Publish & API
Preview is for builders. Production usually means a Web App, the Service API (REST + per-app API keys), and optionally an MCP Server for Cursor-class clients (see MCP on this site). Official difyctl can run the same apps from a shell; see Installation.
Publish the Web App
In Studio, Publish, then enable the Web App. Typical extras: a public link, iframe / chat-bubble embed, light branding and access control (see current Web App Settings).
Good for: colleague trials, a helper on a marketing site. Bad for: stuffing an API key into the browser and calling that an integration. Humans use the Web App; your backend uses the Service API below.
Isolation: API conversations and Web App conversations do not share history. The same business user gets two conversation_id spaces.
Create an API key
Open API Access in the app (sidebar may say “API” or “Develop”):
- Read the generated docs for this app (chat vs workflow paths differ)
- Create an API Key; split
dev/prod; do not share one secret - Store it in server env vars; rotate by adding the new key first
Cloud examples use https://api.dify.ai/v1. Self-host is your site root plus /v1 (via nginx), e.g. http://localhost/v1. Auth header:
Official path: POST /v1/chat-messages
Chat-style apps (Chatflow, Chatbot, Agent, and “New Agent” in the spec) send messages to /chat-messages. With the versioned base that is /v1/chat-messages.
Self-host: http://localhost/v1/chat-messages (or https://your-host/v1/chat-messages).
Single-run workflow apps use a separate workflow run endpoint (see that app’s API page). Do not post those jobs to chat-messages.
Minimal Python client
Add timeouts, retries, and logging in production (never log the raw key). A fuller wrapper is in Practical Examples.
Safety checklist
- Treat keys as passwords; revoke on leak
- One key per app and environment so you can kill a stolen secret
- Browsers call your BFF; only the BFF holds the Dify key
- Check log retention (Cloud vs self-host) for compliance