Agent API Routes#
Dify's console agent API routes live under /console/api/agent (singular) and are split across two controller files in api/controllers/console/agent/:
roster.py— CRUD and lifecycle operations for roster agents (list, create, get, update, delete, publish, draft management, API keys, logs, statistics, versions)composer.py— Agent composition endpoints used by both standalone agents (/agent/<agent_id>/composer) and inline workflow-node agents (/apps/<app_id>/workflows/draft/nodes/<node_id>/agent-composer)
A thin helper module, app_helpers.py, provides resolve_agent_app_model() and resolve_agent_runtime_app_model() to translate the public agent_id UUID to the internal App model via AgentRosterService.
v1.16.0 Plural → Singular Unification (PR #37465)#
PR #37465 (merged ~June 2026) executed a hard rename of every agent route from the old plural namespace to singular:
| Old (plural) | New (singular) |
|---|---|
GET/POST /console/api/agents | GET/POST /console/api/agent |
/agents/<agent_id>/versions | /agent/<agent_id>/versions |
/agents/invite-options | /agent/invite-options |
/apps/<app_id>/agent-composer | /agent/<agent_id>/composer |
/apps/<app_id>/agent-composer/validate | /agent/<agent_id>/composer/validate |
/apps/<app_id>/agent-composer/candidates | /agent/<agent_id>/composer/candidates |
The refactor also changed the primary addressing key: instead of the internal app_id, callers now use the public agent_id. Internal resolution still maps through AgentRosterService.get_agent_app_model() .
Known Bugs from the Refactor#
404 on Agent Creation in Dev Mode (Issue #38646)#
After the unification, the frontend in dev mode was still calling POST /console/api/agents (plural). The backend no longer registered that path, so every agent creation attempt returned 404 . Fix: update frontend calls to POST /console/api/agent (singular).
500 on Agents Configure Page — Custom API Tool Providers (Issue #39169)#
The Agents configure page's credential schema fetch unconditionally used the builtin provider URL template (/tool-provider/builtin/<provider>/credential/...) regardless of providerType. For custom API tools whose tool.id is a UUID (not a plugin identifier), the plugin daemon received a request for langgenius/<UUID> and raised PluginNotFoundError, surfacing as a 500 . Fix (PR #39206): gate both useGetApi and CredentialStatus on providerType !== 'builtin' to short-circuit non-builtin providers before making the request .
Current Route Map (roster.py)#
Key endpoints defined in roster.py:
| Method | Path | Purpose |
|---|---|---|
GET/POST | /agent | List / create agent apps |
GET/PUT/DELETE | /agent/<agent_id> | Get / update / delete agent |
POST | /agent/<agent_id>/publish | Publish draft |
GET/PUT/DELETE | /agent/<agent_id>/build-draft | Draft management |
POST | /agent/<agent_id>/build-draft/checkout | Checkout build draft |
POST | /agent/<agent_id>/build-draft/apply | Apply build draft |
POST | /agent/<agent_id>/copy | Copy agent |
GET/POST | /agent/<agent_id>/api-keys | Manage service API keys |
GET | /agent/<agent_id>/logs | Conversation logs |
GET | /agent/<agent_id>/statistics/summary | Usage statistics |
GET | /agent/<agent_id>/versions | Version history |
POST | /agent/<agent_id>/versions/<version_id>/restore | Restore version |
Agent V2 Backend Plumbing (PR #38162)#
PR #38162 synced Agent V2 daily changes, wiring new services and controllers:
- New services:
api/services/agent_config_service.py,api/services/agent_tool_inner_service.py,api/services/agent/config_skill_normalize_service.py - Inner API controllers:
api/controllers/inner_api/agent/tools.py,api/controllers/inner_api/plugin/agent_config.py - Inspector endpoint:
api/controllers/console/app/agent_config_inspector.pyfor inspecting agent configuration - Config layer rename: The "drive" concept was renamed to "config" throughout the runtime stack —
DifyDriveLayerConfig→DifyConfigLayerConfig;build_drive_layer_config()→build_config_layer_config()
The Agent V2 runtime node itself lives in api/core/workflow/nodes/agent_v2/ and is separate from the console route layer .
API Contract Schemas (PR #37210)#
PR #37210 tightened OpenAPI contract schemas for Agent V2:
- Replaced
dict[str, Any]fields inapi/models/agent_config_entities.pywith typed models (AgentPermissionConfig,AgentCliToolConfig, etc.) - Added
json_schema_extra={"x-dify-opaque": True}to fields that remain intentionally loose at runtime - Removed "inaccurate" deprecation markers from generated
packages/contracts/generated/api/console/agents/orpc.gen.tsto unblock client migration