Skip to main content

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"}'
FieldTypeDefaultDescription
yaml_pathstring or nullrequiredAbsolute path to the YAML app file
forceboolfalseRedeploy 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"}'
FieldTypeDefaultDescription
inputstringrequiredThe user input to process
input_typestring"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?"}'
FieldTypeDescription
session_idstringSession identifier (created on first use)
messagestringUser 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:

EventDescription
connectedStream established
tool_callAgent is calling a tool (name, params)
resultTool execution result
errorTool or agent error
hookRuntime hook fired (e.g., context compaction)
approval_requestA tool call requires user approval
notificationBackground task notification
notification_resultBackground 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"}'
FieldTypeDescription
messagestringUser 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": "."}}'
FieldTypeDefaultDescription
toolstringrequiredTool name in module.action format
paramsdict{}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}'
FieldTypeDefaultDescription
timeoutfloat60.0Max 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"}}'
FieldTypeDefaultDescription
paramsdict{}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": ""}'
FieldTypeDefaultDescription
request_idstringrequiredThe approval request ID
approvedboolrequiredtrue to approve, false to deny
messagestring""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}'
FieldTypeDescription
rpmintRequests 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

Summary: Endpoint Reference

#MethodEndpointDescription
1POST/api/apps/deployDeploy from YAML path
2POST/api/apps/deploy/uploadDeploy from file upload
3GET/api/apps/List deployed apps
4GET/api/apps/{app_id}Get app details
5POST/api/apps/{app_id}/runOne-shot execution
6DELETE/api/apps/{app_id}Undeploy
7POST/api/apps/{app_id}/chatSync conversation turn
8POST/api/apps/{app_id}/chat/streamSSE streaming turn
9GET/api/apps/{app_id}/sessionsList sessions
10GET/api/apps/{app_id}/sessions/{sid}Get session metadata
11GET/api/apps/{app_id}/sessions/{sid}/historyFull message history
12DELETE/api/apps/{app_id}/sessions/{sid}Delete session
13GET/api/apps/{app_id}/sessions/{sid}/eventsPersistent SSE stream
14POST/api/apps/{app_id}/sessions/{sid}/messagesSend message (async)
15POST/api/apps/{app_id}/background-tasksLaunch task
16GET/api/apps/{app_id}/background-tasksList tasks
17GET/api/apps/{app_id}/background-tasks/{id}Get task status
18DELETE/api/apps/{app_id}/background-tasks/{id}Cancel task
19POST/api/apps/{app_id}/background-tasks/{id}/waitWait for task
20GET/api/apps/{app_id}/tools/searchSearch tools
21GET/api/apps/{app_id}/tools/categoriesList categories
22GET/api/apps/{app_id}/tools/categories/{c}Browse category
23GET/api/apps/{app_id}/tools/{name}Get tool schema
24POST/api/apps/{app_id}/tools/{name}/executeExecute tool
25GET/api/apps/{app_id}/indexFull tool index
26POST/api/apps/{app_id}/notificationsDrain notifications (SSE)
27GET/api/apps/{app_id}/notifications/activeCheck for active notifications
28GET/api/apps/{app_id}/approvalsList pending approvals
29POST/api/apps/{app_id}/approveResolve approval
30GET/api/apps/{app_id}/quotaGet rate limit usage
31PUT/api/apps/{app_id}/quotaSet custom rate limit
32DELETE/api/apps/{app_id}/quotaReset rate limit
33GET/api/apps/{app_id}/secretsList secret keys
34GET/api/apps/{app_id}/secrets/{key}Check secret exists
35PUT/api/apps/{app_id}/secrets/{key}Set secret value
36DELETE/api/apps/{app_id}/secrets/{key}Delete secret