REST API Server Tutorial#
This tutorial walks you through starting scafctl’s REST API server and interacting with its endpoints. The API mirrors all major CLI features — solutions, providers, catalogs, schemas, eval, config, and more — over HTTP with OpenAPI documentation.
Prerequisites#
- scafctl installed and on your
$PATH(scafctl versionshould work) - curl or any HTTP client for testing
Quick Start#
Start the Server#
scafctl serveThe server starts on http://localhost:8080 by default.
Verify It Works#
# Root endpoint — lists available API links
curl http://localhost:8080/
# Health check
curl http://localhost:8080/health
# Liveness probe (for orchestrators)
curl http://localhost:8080/health/live
# Readiness probe
curl http://localhost:8080/health/readyConfiguration#
Custom Port and Host#
# Start on a custom port
scafctl serve --port 9090
# Bind to a specific interface
scafctl serve --host 127.0.0.1 --port 3000TLS#
scafctl serve --enable-tls --tls-cert cert.pem --tls-key key.pemConfiguration File#
The API server can be fully configured via the scafctl config file:
apiServer:
host: "127.0.0.1" # use 0.0.0.0 to expose publicly
port: 8080
apiVersion: "v1"
shutdownTimeout: "30s"
requestTimeout: "60s"
maxRequestSize: 10485760 # 10MB
compression:
level: 6
cors:
enabled: true
allowedOrigins:
- "http://localhost:3000"
allowedMethods:
- "GET"
- "POST"
maxAge: 3600
rateLimit:
global:
maxRequests: 100
window: "1m"
audit:
enabled: trueAPI Endpoints#
Solutions#
# List available solutions
curl http://localhost:8080/v1/solutions
# List with CEL filter
curl 'http://localhost:8080/v1/solutions?filter=item.name.startsWith("my-")'
# Lint a solution
curl -X POST http://localhost:8080/v1/solutions/lint \
-H "Content-Type: application/json" \
-d '{"path": "./my-solution"}'
# Render a solution
curl -X POST http://localhost:8080/v1/solutions/render \
-H "Content-Type: application/json" \
-d '{"path": "./my-solution", "inputs": {"name": "test"}}'
# Run a solution (dry-run)
curl -X POST http://localhost:8080/v1/solutions/dryrun \
-H "Content-Type: application/json" \
-d '{"path": "./my-solution", "inputs": {"name": "test"}}'Providers#
# List registered providers
curl http://localhost:8080/v1/providers
# Get provider details
curl http://localhost:8080/v1/providers/file
# Get provider JSON schema
curl http://localhost:8080/v1/providers/file/schemaCEL & Template Evaluation#
# Evaluate a CEL expression
curl -X POST http://localhost:8080/v1/eval/cel \
-H "Content-Type: application/json" \
-d '{"expression": "1 + 2"}'
# Evaluate a Go template
curl -X POST http://localhost:8080/v1/eval/template \
-H "Content-Type: application/json" \
-d '{"template": "Hello, {{.name}}!", "data": {"name": "World"}}'Catalogs#
# List catalogs
curl http://localhost:8080/v1/catalogs
# Get catalog details
curl http://localhost:8080/v1/catalogs/default
# List solutions in a catalog
curl http://localhost:8080/v1/catalogs/default/solutionsConfig & Settings#
# Get current configuration
curl http://localhost:8080/v1/config
# Get runtime settings
curl http://localhost:8080/v1/settingsAdmin Endpoints#
# Server info (version, uptime, provider count)
curl http://localhost:8080/v1/admin/info
# Hot-reload configuration
curl -X POST http://localhost:8080/v1/admin/reload-config
# Clear caches
curl -X POST http://localhost:8080/v1/admin/clear-cachePagination and Filtering#
List endpoints support pagination and CEL filtering:
# Paginate results
curl 'http://localhost:8080/v1/solutions?page=1&per_page=10'
# Filter with CEL expressions
curl 'http://localhost:8080/v1/providers?filter=item.name=="helm"'Metrics and Observability#
# Prometheus metrics
curl http://localhost:8080/metricsThe server also supports OpenTelemetry tracing when configured:
telemetry:
endpoint: "localhost:4317"
insecure: trueOpenAPI Documentation#
The API automatically generates OpenAPI documentation:
# View interactive docs
open http://localhost:8080/v1/docs
# Get OpenAPI spec
curl http://localhost:8080/v1/openapi.json
# Export OpenAPI spec without starting the server
scafctl serve openapi --format json --output openapi.json
scafctl serve openapi --format yaml --output openapi.yamlAuthentication#
When Entra OIDC is enabled, all business endpoints require a valid JWT token:
apiServer:
auth:
azureOIDC:
enabled: true
tenantId: "your-tenant-id"
clientId: "your-client-id"# Authenticated request
curl -H "Authorization: Bearer <token>" http://localhost:8080/v1/solutionsHealth probes (/health, /health/live, /health/ready) and metrics (/metrics) bypass authentication for orchestrator compatibility.
Graceful Shutdown#
The server handles SIGINT and SIGTERM signals gracefully:
- Sets the readiness probe to return 503 (stops receiving new traffic)
- Waits for in-flight requests to complete (up to
shutdownTimeout) - Shuts down cleanly
# Send SIGTERM to gracefully stop
kill -SIGTERM $(pgrep scafctl)