API Integration
Digitorn exposes a REST API for managing deployed apps, running conversations, discovering tools, and handling background tasks. The API serves 36 endpoints under the /api/apps prefix.
Daemon Lifecycle
The API requires the Digitorn daemon to be running.
# Start the daemon
digitorn start
# Start with multiple workers
digitorn start --workers 4
# Stop the daemon
digitorn stop
All API responses are wrapped in a standard envelope:
{
"success": true,
"data": { ... },
"error": null
}
On failure, success is false and error contains a message.
App Lifecycle
Deploy from YAML Path
POST /api/apps/deploy
curl -X POST http://localhost:8000/api/apps/deploy \
-H "Content-Type: application/json" \
-d '{"yaml_path": "/path/to/my-app.yaml"}'
| Field | Type | Default | Description |
|---|---|---|---|
yaml_path | string or null | required | Absolute path to the YAML app file |
force | bool | false | Redeploy even if already deployed |
Response (200):
{
"success": true,
"data": {
"app_id": "my-app",
"name": "My App",
"version": "1.0",
"mode": "conversation",
"agents": ["assistant"],
"modules": ["filesystem", "database"],
"total_tools": 12,
"total_categories": 2,
"deployed_at": 1710300000.0
}
}
Deploy from File Upload
POST /api/apps/deploy/upload
curl -X POST http://localhost:8000/api/apps/deploy/upload \
-F "file=@my-app.yaml"
Accepts the YAML file as multipart form data.
List Deployed Apps
GET /api/apps/
curl http://localhost:8000/api/apps/
Returns a list of AppSummary objects.
Get App Details
GET /api/apps/{app_id}
curl http://localhost:8000/api/apps/my-app
One-Shot Execution
POST /api/apps/{app_id}/run
curl -X POST http://localhost:8000/api/apps/my-app/run \
-H "Content-Type: application/json" \
-d '{"input": "List all Python files in the workspace"}'
| Field | Type | Default | Description |
|---|---|---|---|
input | string | required | The user input to process |
input_type | string | "text" | Input format hint |
Undeploy
DELETE /api/apps/{app_id}
curl -X DELETE http://localhost:8000/api/apps/my-app
Stops all agents, cancels pending approvals, and removes the app from the daemon.
Chat
Synchronous Conversation Turn
POST /api/apps/{app_id}/chat
curl -X POST http://localhost:8000/api/apps/my-app/chat \
-H "Content-Type: application/json" \
-d '{"session_id": "sess-001", "message": "What files are in the workspace?"}'
| Field | Type | Description |
|---|---|---|
session_id | string | Session identifier (created on first use) |
message | string | User message |
Returns the full agent response when the turn completes.
Streaming Conversation Turn (SSE)
POST /api/apps/{app_id}/chat/stream
curl -N -X POST http://localhost:8000/api/apps/my-app/chat/stream \
-H "Content-Type: application/json" \
-d '{"session_id": "sess-001", "message": "Analyze the project structure"}'
Returns a Server-Sent Events stream. Event types:
| Event | Description |
|---|---|
connected | Stream established |
tool_call | Agent is calling a tool (name, params) |
result | Tool execution result |
error | Tool or agent error |
hook | Runtime hook fired (e.g., context compaction) |
approval_request | A tool call requires user approval |
notification | Background task notification |
notification_result | Background task completed |
Example SSE output:
event: connected
data: {"session_id": "sess-001"}
event: tool_call
data: {"name": "filesystem.ls", "params": {"path": "."}}
event: result
data: {"success": true, "data": ["src/", "tests/", "README.md"]}
event: tool_call
data: {"name": "filesystem.read", "params": {"path": "README.md"}}
event: result
data: {"success": true, "data": "# My Project\n..."}
The final response is the last data payload before the stream closes.
Sessions
Sessions persist conversation history across multiple turns. They are scoped per app and expire after 1 hour of inactivity by default.
List Sessions
GET /api/apps/{app_id}/sessions
curl http://localhost:8000/api/apps/my-app/sessions
Get Session Metadata
GET /api/apps/{app_id}/sessions/{session_id}
curl http://localhost:8000/api/apps/my-app/sessions/sess-001
Get Full Message History
GET /api/apps/{app_id}/sessions/{session_id}/history
curl http://localhost:8000/api/apps/my-app/sessions/sess-001/history
Delete Session
DELETE /api/apps/{app_id}/sessions/{session_id}
curl -X DELETE http://localhost:8000/api/apps/my-app/sessions/sess-001
Persistent SSE Event Stream
GET /api/apps/{app_id}/sessions/{session_id}/events
curl -N http://localhost:8000/api/apps/my-app/sessions/sess-001/events
This is the primary SDK endpoint. The connection stays open for the session lifetime and auto-pushes all events: tool calls, results, errors, background task notifications, and approval requests.
A client should open this stream once and keep it open, then send messages via the async message endpoint below.
Send Message (Async)
POST /api/apps/{app_id}/sessions/{session_id}/messages
curl -X POST http://localhost:8000/api/apps/my-app/sessions/sess-001/messages \
-H "Content-Type: application/json" \
-d '{"message": "Read the config file"}'
| Field | Type | Description |
|---|---|---|
message | string | User message |
Returns 202 Accepted immediately. The agent processes the message asynchronously and pushes the response through the persistent SSE stream (/sessions/{sid}/events).
Background Tasks
Background tasks let you launch long-running tool executions without blocking the conversation.
Launch Task
POST /api/apps/{app_id}/background-tasks
curl -X POST http://localhost:8000/api/apps/my-app/background-tasks \
-H "Content-Type: application/json" \
-d '{"tool": "filesystem.find", "params": {"pattern": "*.py", "path": "."}}'
| Field | Type | Default | Description |
|---|---|---|---|
tool | string | required | Tool name in module.action format |
params | dict | {} | Tool parameters |
List Tasks
GET /api/apps/{app_id}/background-tasks
curl http://localhost:8000/api/apps/my-app/background-tasks
Get Task Status
GET /api/apps/{app_id}/background-tasks/{task_id}
curl http://localhost:8000/api/apps/my-app/background-tasks/task-123
Cancel Task
DELETE /api/apps/{app_id}/background-tasks/{task_id}
curl -X DELETE http://localhost:8000/api/apps/my-app/background-tasks/task-123
Wait for Task
POST /api/apps/{app_id}/background-tasks/{task_id}/wait
curl -X POST http://localhost:8000/api/apps/my-app/background-tasks/task-123/wait \
-H "Content-Type: application/json" \
-d '{"timeout": 30.0}'
| Field | Type | Default | Description |
|---|---|---|---|
timeout | float | 60.0 | Max seconds to wait before returning |
Blocks until the task completes or the timeout is reached.
Tool Discovery
These endpoints expose the same tool discovery capabilities that agents use internally via meta-tools.
Search Tools
GET /api/apps/{app_id}/tools/search?query=read+file
curl "http://localhost:8000/api/apps/my-app/tools/search?query=read+file"
Uses hybrid semantic + keyword search. Returns ranked tool matches.
List Categories
GET /api/apps/{app_id}/tools/categories
curl http://localhost:8000/api/apps/my-app/tools/categories
Browse Category (Paginated)
GET /api/apps/{app_id}/tools/categories/{category}
curl http://localhost:8000/api/apps/my-app/tools/categories/filesystem
Get Tool Schema
GET /api/apps/{app_id}/tools/{tool_name}
curl http://localhost:8000/api/apps/my-app/tools/filesystem.read
Returns the full JSON schema, description, parameter details, side effects, and aliases.
Execute Tool Directly
POST /api/apps/{app_id}/tools/{tool_name}/execute
curl -X POST http://localhost:8000/api/apps/my-app/tools/filesystem.read/execute \
-H "Content-Type: application/json" \
-d '{"params": {"path": "/home/user/project/README.md"}}'
| Field | Type | Default | Description |
|---|---|---|---|
params | dict | {} | Tool parameters |
Security policies (grant/approve/deny from the app's capabilities: block) still apply to direct tool execution.
Index
Get Full Tool Index
GET /api/apps/{app_id}/index
curl http://localhost:8000/api/apps/my-app/index
Returns the complete tool index structure: all categories, tools, schemas, and metadata.
Notifications
Notifications are generated by background tasks that complete while the agent is in a conversation turn.
Check for Active Notifications
GET /api/apps/{app_id}/notifications/active
curl http://localhost:8000/api/apps/my-app/notifications/active
Returns { "active": true } or { "active": false }. This is a lightweight poll endpoint for clients that need a quick check.
Drain Notifications (SSE)
POST /api/apps/{app_id}/notifications
curl -N -X POST http://localhost:8000/api/apps/my-app/notifications
Drains all pending notifications and triggers an agent turn to process them. Returns results as an SSE stream.
Approvals
When an app defines a capabilities: block with approve: rules, certain tool calls require explicit user approval before execution.
List Pending Approvals
GET /api/apps/{app_id}/approvals
curl http://localhost:8000/api/apps/my-app/approvals
Resolve an Approval
POST /api/apps/{app_id}/approve
curl -X POST http://localhost:8000/api/apps/my-app/approve \
-H "Content-Type: application/json" \
-d '{"request_id": "req-abc", "approved": true, "message": ""}'
| Field | Type | Default | Description |
|---|---|---|---|
request_id | string | required | The approval request ID |
approved | bool | required | true to approve, false to deny |
message | string | "" | Optional message for the agent |
Pending approvals time out after 5 minutes and are auto-denied.
When using the streaming chat endpoint (/chat/stream), approval requests are pushed as approval_request SSE events. The client should display the request to the user and POST the decision back to this endpoint.
Rate Limiting
Per-app rate limiting uses a sliding window counter. The default limit is 60 requests per minute, applied to /chat, /run, and /chat/stream endpoints.
Get Current Usage
GET /api/apps/{app_id}/quota
curl http://localhost:8000/api/apps/my-app/quota
Set Custom Limit
PUT /api/apps/{app_id}/quota
curl -X PUT http://localhost:8000/api/apps/my-app/quota \
-H "Content-Type: application/json" \
-d '{"rpm": 120}'
| Field | Type | Description |
|---|---|---|
rpm | int | Requests per minute |
Reset to Default
DELETE /api/apps/{app_id}/quota
curl -X DELETE http://localhost:8000/api/apps/my-app/quota
Secrets
Per-app encrypted secret storage. Secrets are stored with Fernet encryption and never returned in plaintext by the API.
List secret keys
GET /api/apps/{app_id}/secrets
curl http://localhost:8000/api/apps/my-app/secrets
Response (200):
{
"success": true,
"data": { "app_id": "my-app", "keys": ["API_KEY", "CLIENT_SECRET"] }
}
Check if a secret exists
GET /api/apps/{app_id}/secrets/{key}
curl http://localhost:8000/api/apps/my-app/secrets/API_KEY
Response (200):
{
"success": true,
"data": { "app_id": "my-app", "key": "API_KEY", "exists": true }
}
Set a secret
PUT /api/apps/{app_id}/secrets/{key}
curl -X PUT http://localhost:8000/api/apps/my-app/secrets/API_KEY \
-H "Content-Type: application/json" \
-d '{"value": "sk-live-abc123"}'
Delete a secret
DELETE /api/apps/{app_id}/secrets/{key}
curl -X DELETE http://localhost:8000/api/apps/my-app/secrets/API_KEY
CLI commands
digitorn secret set my-app API_KEY "sk-live-abc123"
digitorn secret set my-app API_KEY # prompts for value (hidden)
digitorn secret list my-app
digitorn secret delete my-app API_KEY
SDK Integration Pattern
The recommended flow for building a client application on top of the Digitorn API:
1. Deploy the App
curl -X POST http://localhost:8000/api/apps/deploy \
-d '{"yaml_path": "/path/to/app.yaml"}'
2. Open a Persistent SSE Stream
curl -N http://localhost:8000/api/apps/my-app/sessions/sess-001/events
Keep this connection open for the session lifetime. All events (tool calls, results, errors, approvals, background notifications) arrive here.
3. Send Messages Asynchronously
curl -X POST http://localhost:8000/api/apps/my-app/sessions/sess-001/messages \
-d '{"message": "Analyze the project"}'
# Returns 202 immediately
The response arrives via the SSE stream opened in step 2.
4. Handle Approvals
When an approval_request event arrives on the SSE stream, display it to the user and resolve it:
curl -X POST http://localhost:8000/api/apps/my-app/approve \
-d '{"request_id": "req-abc", "approved": true}'
5. Launch Background Tasks
curl -X POST http://localhost:8000/api/apps/my-app/background-tasks \
-d '{"tool": "database.query", "params": {"sql": "SELECT count(*) FROM users"}}'
Background task completions are pushed as notification events on the persistent SSE stream.
6. Poll or Wait for Tasks
For clients that do not use the persistent SSE stream:
# Quick check
curl http://localhost:8000/api/apps/my-app/notifications/active
# Block until task completes
curl -X POST http://localhost:8000/api/apps/my-app/background-tasks/task-123/wait \
-d '{"timeout": 30.0}'
7. Clean Up
# Delete session
curl -X DELETE http://localhost:8000/api/apps/my-app/sessions/sess-001
# Undeploy app
curl -X DELETE http://localhost:8000/api/apps/my-app