Get started in less than 5 minInstall now

Api Docs

Knodex exposes a REST API at /api/v1/ for managing RGD catalogs, instances, projects, and RBAC. This guide covers authentication, interactive exploration with Swagger UI, and working curl examples.

Prerequisites

  • Running Knodex environment (Tilt or QA deployment)
  • curl and jq installed

Start the Dev Environment

# One-time: create Kind cluster with KRO + CRDs
make cluster-up
 
# Start Tilt with enterprise features
tilt up -- --enterprise

This gives you:

Swagger UI

Swagger UI is disabled by default in production but automatically enabled in Tilt dev environments. To enable it manually, set SWAGGER_UI_ENABLED=true.

Open http://localhost:8080/swagger/ in your browser to explore the API interactively.

To authenticate in Swagger UI:

  1. Obtain a token (see below)
  2. Click the Authorize button
  3. Enter Bearer <token> in the value field
  4. Click Authorize

All "Try it out" requests will include your token automatically.

Obtain a JWT Token

Local Admin Login

# Login with the local admin account
TOKEN=$(curl -s http://localhost:8080/api/v1/auth/local/login \
  -H "Content-Type: application/json" \
  -d '{"username":"admin","password":"YOUR_PASSWORD"}' \
  | jq -r '.token')
 
echo $TOKEN

The admin password is auto-generated on first cluster start. Find it with:

# Tilt environment
kubectl get secret knodex-initial-admin-password -n knodex-tilt -o jsonpath='{.data.password}' | base64 -d
 
# QA environment
kubectl get secret knodex-initial-admin-password -n knodex -o jsonpath='{.data.password}' | base64 -d

OIDC Login

OIDC authentication uses a browser-based flow:

  1. Navigate to http://localhost:8080/api/v1/auth/oidc/login?provider=default&redirect=http://localhost:3000
  2. Authenticate with your identity provider
  3. The callback redirects to the frontend with an auth code
  4. Exchange the code for a token:
TOKEN=$(curl -s http://localhost:8080/api/v1/auth/token-exchange \
  -H "Content-Type: application/json" \
  -d '{"code":"AUTH_CODE_FROM_REDIRECT"}' \
  | jq -r '.token')

Use the Token

Include the token in all API requests:

curl -s http://localhost:8080/api/v1/rgds \
  -H "Authorization: Bearer $TOKEN" | jq

Tokens expire after 1 hour. Re-authenticate to obtain a new one.

API Examples

List RGDs (Catalog)

# List all catalog RGDs
curl -s http://localhost:8080/api/v1/rgds \
  -H "Authorization: Bearer $TOKEN" | jq
 
# Filter by category
curl -s "http://localhost:8080/api/v1/rgds?category=database" \
  -H "Authorization: Bearer $TOKEN" | jq
 
# Search by name
curl -s "http://localhost:8080/api/v1/rgds?search=postgres" \
  -H "Authorization: Bearer $TOKEN" | jq

Get RGD Details

curl -s http://localhost:8080/api/v1/rgds/my-rgd-name \
  -H "Authorization: Bearer $TOKEN" | jq

List Projects

curl -s http://localhost:8080/api/v1/projects \
  -H "Authorization: Bearer $TOKEN" | jq

Create a Project

curl -s http://localhost:8080/api/v1/projects \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-project",
    "description": "My test project",
    "destinations": [{"namespace": "my-namespace"}]
  }' | jq

Deploy an Instance

# Direct deployment
curl -s http://localhost:8080/api/v1/instances \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "my-instance",
    "namespace": "my-namespace",
    "rgdName": "my-rgd-name",
    "projectId": "my-project",
    "spec": {},
    "deploymentMode": "direct"
  }' | jq

Check Permissions (can-i)

# Can I create projects?
curl -s http://localhost:8080/api/v1/account/can-i/projects/create/* \
  -H "Authorization: Bearer $TOKEN" | jq
 
# Can I deploy to a specific project?
curl -s http://localhost:8080/api/v1/account/can-i/instances/create/my-project \
  -H "Authorization: Bearer $TOKEN" | jq

Get Account Info

curl -s http://localhost:8080/api/v1/account/info \
  -H "Authorization: Bearer $TOKEN" | jq

Enterprise vs OSS

Enterprise endpoints require the server to be built with -tags=enterprise (Tilt with --enterprise flag does this automatically).

FeatureOSS ResponseEnterprise Response
Compliance (/api/v1/compliance/*)404 Not FoundFull data
Audit trail (/api/v1/settings/audit/*)404 Not FoundFull data
Custom views (/api/v1/ee/views)404 Not FoundFull data
License (/api/v1/license)404 Not FoundLicense status

Toggle enterprise mode in Tilt:

# Enterprise (default with --enterprise flag)
tilt up -- --enterprise
 
# OSS only
tilt up

Rate Limits

EndpointLimitScope
POST /api/v1/auth/local/login5 req/minPer IP
GET /api/v1/auth/oidc/login20 req/minPer IP
GET /api/v1/auth/oidc/callback5 req/minPer IP
GET /api/v1/auth/oidc/providers30 req/minPer IP
GET /api/v1/projects/{name}/namespaces20 req/minPer IP
All other protected endpoints100 req/minPer user

Exceeding the limit returns 429 Too Many Requests.

Error Response Format

All API errors follow a consistent JSON format:

{
  "code": "NOT_FOUND",
  "message": "RGD not found: my-rgd",
  "details": {
    "resource": "RGD",
    "identifier": "my-rgd"
  }
}

Error codes: BAD_REQUEST, UNAUTHORIZED, FORBIDDEN, NOT_FOUND, VALIDATION_FAILED, RATE_LIMIT_EXCEEDED, SERVICE_UNAVAILABLE, INTERNAL_ERROR, METHOD_NOT_ALLOWED.

OpenAPI Specification

The complete OpenAPI 3.0.3 specification is available at:

Validate the Spec

make api-docs

Regenerate

The OpenAPI spec is maintained manually in docs/api/openapi.yaml. After modifying it, validate and sync with:

make api-docs

This validates the spec with Redocly CLI and copies it to the server embed directory (server/internal/api/swagger/openapi.yaml).

WebSocket API

Real-time updates use WebSocket at /ws. Authentication uses a single-use ticket:

# 1. Get a ticket
TICKET=$(curl -s http://localhost:8080/api/v1/ws/ticket \
  -H "Authorization: Bearer $TOKEN" \
  -X POST | jq -r '.ticket')
 
# 2. Connect with the ticket
wscat -c "ws://localhost:8080/ws?ticket=$TICKET"

Next Steps