Skip to Content
DojOps: AI-powered DevOps automation. Learn more →
TutorialsAPI Server & Dashboard

API server & dashboard

Run DojOps as a persistent HTTP service. Connect your team, CI/CD pipelines, and custom scripts to a shared LLM infrastructure.

Difficulty: Intermediate Duration: 30 minutes What you’ll build: A running DojOps API server with authentication, a CI/CD integration script that triggers security scans, and a chat session managed via the REST API


What you’ll learn

  • How to start the API server and configure authentication for team use
  • When to use TLS and how to enable it
  • What each tab in the web dashboard shows and how to read the metrics
  • How to call every major endpoint from curl and shell scripts
  • How to wire the API into a GitHub Actions pipeline for security scanning

Prerequisites

  • DojOps 1.1.6 installed: npm i -g @dojops/cli
  • A project initialized: dojops init
  • An LLM provider configured: dojops provider add openai --token sk-...

Workshop steps

Step 1: Start the server

The serve command launches an Express API server and the web dashboard on the same port:

dojops serve
┌ DojOps API Server v1.1.6 │ Dashboard: http://localhost:3000 │ API Base: http://localhost:3000/api/v1 │ Provider: openai / gpt-4o │ Auth: disabled (local mode) │ Press Ctrl+C to stop └ Server ready

The server starts in unauthenticated local mode — all endpoints are open. Open http://localhost:3000 in your browser and you’ll see the dashboard loading.

Use a custom port if 3000 is taken:

dojops serve --port=8080

Override the LLM provider for this server instance without changing your global config:

dojops serve --provider=anthropic

Step 2: Generate API credentials

Before sharing the server with your team or exposing it beyond localhost, generate an API key:

dojops serve credentials
┌ API Credentials │ API Key: dojops_sv_a1b2c3d4e5f6789abcdef0123456789abcdef01 │ Saved to: ~/.dojops/server.json │ Use this key in the Authorization header: │ Authorization: Bearer dojops_sv_a1b2c3d4e5f6789abcdef0123456789abcdef01 └ Key generated - server will auto-load on next start

The key is hashed and stored in ~/.dojops/server.json. From now on, every time you run dojops serve, the key is automatically loaded and all endpoints require it.

Restart the server to activate authentication:

dojops serve
┌ DojOps API Server v1.1.6 │ Dashboard: http://localhost:3000 │ API Base: http://localhost:3000/api/v1 │ Auth: API key required └ Server ready

Requests without the key now get a 401. This includes the web dashboard — when you open http://localhost:3000 in your browser, you’ll see a login screen asking for the API key. Paste the key from dojops serve credentials to log in.

Important: Copy the API key when it’s displayed. The key is hashed before storage, so you can’t retrieve it later. If you lose it, run dojops serve credentials again to generate a new one.

For local development where you don’t want authentication overhead:

dojops serve --no-auth

Never expose a --no-auth server to the network. It’s for localhost-only development.

Step 3: Enable TLS for production

If you’re running the API server behind a domain or exposing it to the network, add TLS:

dojops serve --tls-cert=cert.pem --tls-key=key.pem
┌ DojOps API Server v1.1.6 │ Dashboard: https://localhost:3000 │ API Base: https://localhost:3000/api/v1 │ Auth: API key required │ TLS: ✓ enabled └ Server ready

Combine with a non-standard port for production deployments:

dojops serve --tls-cert=/etc/ssl/dojops/cert.pem \ --tls-key=/etc/ssl/dojops/key.pem \ --port=8443

For most team setups, running dojops serve on an internal port behind an nginx or Caddy reverse proxy — which handles TLS termination — is simpler than managing certificates directly.

Step 4: Explore the web dashboard

Open http://localhost:3000 in your browser. If you generated credentials in Step 2, the dashboard will show a login screen — paste your API key to authenticate. The dashboard has five tabs. After a few operations, each tab fills in with real data.

Overview tab — Plan execution totals, success and failure rates, recent activity timeline. If you’ve run dojops apply a few times, you’ll see task counts grouped by skill type.

Security tab — Findings from every dojops scan run, grouped by severity (CRITICAL, HIGH, MEDIUM, LOW) and by scanner (trivy, gitleaks, checkov, hadolint, semgrep, and the rest). The trend chart shows how your security posture changes over time.

Audit tab — The hash-chained audit log rendered as a timeline. Each entry shows the operation type, timestamp, and whether its hash is valid. A broken chain shows up in red — that’s a sign of log tampering or corruption.

Agents tab — All 32 built-in specialist agents plus any custom agents you’ve created. Each agent shows its domain, keyword list, and how many prompts have been routed to it.

History tab — Every plan execution with per-task status and timing. Filter by status (completed, partial, failed) or by date range to find a specific run.

Step 5: Verify the server is running

Before scripting against the API, confirm the server responds:

curl http://localhost:3000/api/health
{ "status": "ok", "version": "1.1.6", "provider": "openai", "model": "gpt-4o", "customSkillCount": 2, "customAgentCount": 1 }

The health endpoint doesn’t require authentication. It’s safe to use as a readiness probe in Kubernetes or a load balancer health check.

Step 6: Generate a DevOps config via API

Use the generate endpoint to get LLM output routed through the agent system:

curl -X POST http://localhost:3000/api/generate \ -H "Content-Type: application/json" \ -H "Authorization: Bearer dojops_sv_a1b2c3d4e5f6789abcdef0123456789abcdef01" \ -d '{"prompt": "Create a multi-stage Dockerfile for a Go application"}'
{ "content": "FROM golang:1.22-alpine AS builder\nWORKDIR /app\nCOPY go.mod go.sum ./\nRUN go mod download\nCOPY . .\nRUN CGO_ENABLED=0 GOOS=linux go build -o main .\n\nFROM scratch\nCOPY --from=builder /app/main /main\nENTRYPOINT [\"/main\"]", "agent": "docker-specialist", "skill": null, "tokensUsed": 312 }

The agent was selected automatically by the router. Specify an agent explicitly to override routing:

curl -X POST http://localhost:3000/api/generate \ -H "Content-Type: application/json" \ -H "Authorization: Bearer YOUR_API_KEY" \ -d '{"prompt": "Optimize this Dockerfile", "agent": "docker-specialist"}'

Step 7: Create and execute a plan

The plan endpoint lets you create a TaskGraph and optionally execute it in one call:

curl -X POST http://localhost:3000/api/plan \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "goal": "Set up CI/CD for a Python project with pytest and Docker", "execute": true }'
{ "planId": "plan-9c3a7d12", "tasks": [ { "id": 1, "name": "github-actions", "status": "completed", "file": ".github/workflows/ci.yml" }, { "id": 2, "name": "dockerfile", "status": "completed", "file": "Dockerfile" }, { "id": 3, "name": "pytest-config", "status": "completed", "file": "pytest.ini" } ], "summary": "3/3 tasks completed", "tokensUsed": 1847 }

Without "execute": true, the endpoint returns the plan structure without running it — equivalent to dojops plan without dojops apply.

Step 8: Run a security scan

The scan endpoint runs one or more security scanners against your project:

curl -X POST http://localhost:3000/api/scan \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"scanTypes": ["security", "deps", "iac"]}'
{ "findings": [ { "scanner": "trivy", "severity": "HIGH", "title": "CVE-2024-1234 in lodash@4.17.20", "file": "package.json", "line": null }, { "scanner": "checkov", "severity": "MEDIUM", "title": "Ensure S3 bucket has versioning enabled", "file": "main.tf", "line": 14 } ], "summary": { "CRITICAL": 0, "HIGH": 1, "MEDIUM": 1, "LOW": 4 } }

Available scan types: security, deps, iac, containers, secrets, licenses. Pass multiple types to run them in parallel.

Step 9: Debug a CI failure

Paste a CI log into the debug-ci endpoint to get a structured diagnosis:

curl -X POST http://localhost:3000/api/debug-ci \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "log": "npm ERR! ERESOLVE unable to resolve dependency tree\nnpm ERR! While resolving: my-app@1.0.0\nnpm ERR! Found: react@18.2.0\nnpm ERR! node_modules/react\nnpm ERR! peer react@^17.0.0 from react-dom@17.0.2" }'
{ "diagnosis": "Peer dependency conflict: react-dom@17.0.2 requires React 17, but React 18 is installed.", "rootCause": "react-dom version is pinned to 17.x which only supports React 17.", "fix": "Upgrade react-dom to 18.x: npm install react-dom@^18.2.0", "commands": ["npm install react-dom@^18.2.0"], "confidence": "high" }

Step 10: Manage chat sessions

For multi-turn conversations with context, use the chat session API:

# Create a session curl -X POST http://localhost:3000/api/chat/sessions \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"name": "infra-planning-session"}'
{ "id": "sess-7f3a12bc", "name": "infra-planning-session", "createdAt": "2026-03-20T14:00:00Z" }
# Send messages in the session curl -X POST http://localhost:3000/api/chat \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "message": "We need Terraform for AWS ECS. What modules do we need?", "sessionId": "sess-7f3a12bc" }'
{ "response": "For AWS ECS with Terraform, you'll need these core modules: ...", "agent": "terraform-specialist", "sessionId": "sess-7f3a12bc", "tokensUsed": 428 }

List and delete sessions:

# List all sessions curl http://localhost:3000/api/chat/sessions \ -H "Authorization: Bearer YOUR_API_KEY" # Delete a session curl -X DELETE http://localhost:3000/api/chat/sessions/sess-7f3a12bc \ -H "Authorization: Bearer YOUR_API_KEY"

Step 11: Pull dashboard metrics

The metrics endpoints power the dashboard — you can also call them directly for monitoring integrations:

# All metrics in one call curl http://localhost:3000/api/metrics \ -H "Authorization: Bearer YOUR_API_KEY" # Just the overview curl http://localhost:3000/api/metrics/overview \ -H "Authorization: Bearer YOUR_API_KEY"
{ "totalPlans": 24, "completedPlans": 21, "failedPlans": 3, "totalTasksExecuted": 87, "successRate": 0.875, "lastActivityAt": "2026-03-20T14:30:00Z" }

Token usage tracking is on its own endpoint — useful for cost monitoring:

curl http://localhost:3000/api/metrics/tokens \ -H "Authorization: Bearer YOUR_API_KEY"

Step 12: Wire into a GitHub Actions pipeline

Use the DojOps API as a shared security scanning service from your CI:

name: CI on: [push, pull_request] jobs: security-scan: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Run DojOps Security Scan id: scan run: | RESULT=$(curl -s -X POST ${{ secrets.DOJOPS_API_URL }}/api/scan \ -H "Authorization: Bearer ${{ secrets.DOJOPS_API_KEY }}" \ -H "Content-Type: application/json" \ -d '{"scanTypes": ["security", "secrets", "iac"]}') echo "result=$RESULT" >> $GITHUB_OUTPUT CRITICAL=$(echo "$RESULT" | jq '.summary.CRITICAL') if [ "$CRITICAL" -gt 0 ]; then echo "::error::$CRITICAL CRITICAL finding(s) detected. Review security scan results." exit 1 fi - name: Post Scan Summary if: always() run: | echo "${{ steps.scan.outputs.result }}" | \ jq -r '.findings[] | "[\(.severity)] \(.scanner): \(.title)"'

Set DOJOPS_API_URL and DOJOPS_API_KEY as repository secrets. The pipeline fails the build on any CRITICAL finding and prints a summary of all findings.


Try it yourself

  1. Build a metrics monitor. Write a shell script that calls /api/metrics/security every hour and posts a Slack message if the CRITICAL count increases. Use jq to extract the count and curl to POST to a Slack webhook.

  2. Multi-provider comparison. Start two DojOps servers on different ports, one using OpenAI and one using Anthropic. Write a shell function that sends the same prompt to both and prints the responses side by side.

  3. Chat session workflow. Create a chat session, send three related questions about Kubernetes in sequence, then call GET /api/chat/sessions/:id to retrieve the full conversation history and save it to a Markdown file.


Troubleshooting

Server returns 401 on all requests after generating credentials

The API key is hashed in ~/.dojops/server.json. Make sure you’re sending the original key in the Authorization: Bearer ... header — not the hash. If you’ve lost the key, run dojops serve credentials again to generate a new one.

Dashboard shows no data even after several runs

The dashboard reads metrics from .dojops/ in the directory where dojops serve was launched. Make sure you’re starting the server from the same project directory where you ran dojops apply and dojops scan.

TLS handshake errors from curl

If using a self-signed certificate, pass -k to curl to skip verification during development: curl -k https://localhost:3000/api/health. In production, use a certificate signed by a recognized CA.

Scan endpoint times out

Some scanners (trivy, semgrep) take longer on large codebases. The default scan timeout is 120 seconds. Increase it with DOJOPS_SCAN_TIMEOUT_MS=300000 in your environment before starting the server.


What you learned

The DojOps API server turns the CLI into a shared service. Authentication uses a hashed API key that’s generated once and loaded automatically on startup. The 23 REST endpoints cover every CLI operation — generation, planning, scanning, debugging, and chat — so any team member or automated system can access the same LLM infrastructure. The web dashboard aggregates all of this into live metrics without requiring a separate database. The hash-chained audit log on the Audit tab gives you a tamper-evident record that works for both internal review and compliance requirements.


Next steps