Skip to main content

Endpoint

POST /v1/generate
Generates a complete OpenClaw stack including docker-compose.yml, .env files, reverse proxy configs, monitoring dashboards, and agent skill files. Supports multiple output formats: JSON (default), complete JSON with metadata, and ZIP archive.

Authentication

X-API-Key
string
Optional API key for authenticated requests with higher rate limits

Query Parameters

format
string
Output format for the generated stack:
  • json (default) - Returns files as JSON object with metadata
  • complete - Returns input + files + metadata for export/import
  • zip - Returns binary ZIP archive (also triggered by Accept: application/zip header)

Request Body

projectName
string
required
Name of the project (used for directory name and Docker Compose project name)
services
array
Array of service IDs to include (e.g., ["postgresql", "redis", "n8n"]). Required unless using a preset.
skillPacks
array
Array of skill pack IDs to include (e.g., ["devops", "research"]). Skill packs automatically add their required services.
proxy
string
Reverse proxy to use: caddy or traefik. Auto-generates proxy configuration files.
domain
string
Base domain for service URLs (e.g., example.com). Services will be available at subdomains like n8n.example.com.
gpu
boolean
default:"false"
Enable GPU support for AI/ML services (adds Docker runtime configuration)
platform
string
Target platform: linux/amd64 or linux/arm64. Defaults to host platform.
deployment
string
Deployment type: docker (default) or bare-metal. Bare-metal generates hybrid native + Docker install scripts.
generateSecrets
boolean
default:"true"
Auto-generate secure random secrets for passwords and API keys
openclawVersion
string
OpenClaw version to target (e.g., latest, v1.2.3). Defaults to latest stable.

Response

Default JSON Format

files
object
required
Object mapping file paths to file contents. All files are UTF-8 strings.
metadata
object
required
Generation metadata

Complete JSON Format

formatVersion
string
Format version (currently "1")
input
object
Original request body (for re-generation)
files
object
Same as default format
metadata
object
Same as default format

ZIP Format

Returns binary ZIP archive with Content-Type: application/zip and Content-Disposition: attachment headers.

Examples

Basic Stack Generation

curl -X POST http://localhost:3456/v1/generate \
  -H "Content-Type: application/json" \
  -d '{
    "projectName": "my-stack",
    "services": ["postgresql", "redis", "n8n"],
    "proxy": "caddy",
    "domain": "example.com"
  }'
Response (200):
{
  "files": {
    "docker-compose.yml": "version: '3.8'\nservices:\n  postgresql:\n    image: postgres:16-alpine\n    ports:\n      - 5432:5432\n    environment:\n      POSTGRES_USER: openclaw\n      POSTGRES_PASSWORD: ${POSTGRES_PASSWORD}\n      POSTGRES_DB: openclaw\n    volumes:\n      - postgres_data:/var/lib/postgresql/data\n    healthcheck:\n      test: ['CMD-SHELL', 'pg_isready -U openclaw']\n      interval: 10s\n      timeout: 5s\n      retries: 5\n\n  redis:\n    image: redis:7-alpine\n    ports:\n      - 6379:6379\n    volumes:\n      - redis_data:/data\n\n  n8n:\n    image: n8nio/n8n:latest\n    ports:\n      - 5678:5678\n    environment:\n      DB_TYPE: postgresdb\n      DB_POSTGRESDB_HOST: postgresql\n      DB_POSTGRESDB_DATABASE: openclaw\n      DB_POSTGRESDB_USER: openclaw\n      DB_POSTGRESDB_PASSWORD: ${POSTGRES_PASSWORD}\n      N8N_PROTOCOL: https\n      N8N_HOST: n8n.example.com\n    depends_on:\n      - postgresql\n      - redis\n\nvolumes:\n  postgres_data:\n  redis_data:\n",
    ".env": "# PostgreSQL\nPOSTGRES_PASSWORD=gHj9kL2mP5qR8sT1vW4xZ7\n\n# n8n\nN8N_ENCRYPTION_KEY=aB3dE6fG9hJ2kL5mN8pQ1rS4tU7vW0xY3zA6bC9dE2fG5hJ8kL1mN4pQ7rS0tU3vW6xY9zA2bC5dE8fG1hJ4kL7mN0pQ3rS6tU9vW2xY5zA8bC1dE4fG7hJ0kL3mN6pQ9rS2tU5vW8xY1zA4bC7dE0fG3hJ6kL9mN2pQ5rS8tU1vW4xY7zA0bC3dE6fG9hJ2kL5mN8",
    "Caddyfile": "n8n.example.com {\n  reverse_proxy n8n:5678\n}\n",
    "README.md": "# my-stack\n\nGenerated OpenClaw stack with:\n- PostgreSQL\n- Redis\n- n8n\n\n## Quick Start\n\n```bash\n# Start the stack\ndocker compose up -d\n\n# Check status\ndocker compose ps\n\n# View logs\ndocker compose logs -f\n\n# Stop the stack\ndocker compose down\n```\n\n## Access Services\n\n- n8n: https://n8n.example.com\n\n## Environment Variables\n\nAll secrets are stored in `.env`. Never commit this file to version control.\n"
  },
  "metadata": {
    "generatedAt": "2026-03-03T10:30:00.000Z",
    "totalServices": 3,
    "estimatedMemoryMB": 896,
    "resolvedDependencies": ["postgresql"],
    "warnings": []
  }
}

Generate with Skill Packs

curl -X POST http://localhost:3456/v1/generate \
  -H "Content-Type: application/json" \
  -d '{
    "projectName": "research-stack",
    "services": [],
    "skillPacks": ["research"],
    "proxy": "caddy",
    "domain": "research.local"
  }'
Skill packs automatically add their required services (Qdrant, SearXNG, Browserless, Redis).

Generate as ZIP

curl -X POST "http://localhost:3456/v1/generate?format=zip" \
  -H "Content-Type: application/json" \
  -d '{
    "projectName": "devops-stack",
    "services": ["n8n", "postgresql", "redis", "grafana", "prometheus"]
  }' \
  --output devops-stack.zip
Or use the Accept header:
curl -X POST http://localhost:3456/v1/generate \
  -H "Content-Type: application/json" \
  -H "Accept: application/zip" \
  -d '{"projectName": "stack", "services": ["redis"]}' \
  --output stack.zip

Generate Complete JSON

curl -X POST "http://localhost:3456/v1/generate?format=complete" \
  -H "Content-Type: application/json" \
  -d '{
    "projectName": "export-stack",
    "services": ["postgresql", "redis"]
  }'
Response (200):
{
  "formatVersion": "1",
  "input": {
    "projectName": "export-stack",
    "services": ["postgresql", "redis"]
  },
  "files": {
    "docker-compose.yml": "...",
    ".env": "..."
  },
  "metadata": {
    "generatedAt": "2026-03-03T10:30:00.000Z",
    "totalServices": 2,
    "estimatedMemoryMB": 384
  }
}

GPU-Enabled Stack

curl -X POST http://localhost:3456/v1/generate \
  -H "Content-Type: application/json" \
  -d '{
    "projectName": "ai-stack",
    "services": ["ollama", "stable-diffusion", "open-webui"],
    "gpu": true
  }'
Adds Docker runtime configuration for GPU passthrough.

Bare-Metal Deployment

curl -X POST http://localhost:3456/v1/generate \
  -H "Content-Type: application/json" \
  -d '{
    "projectName": "hybrid-stack",
    "services": ["redis", "postgresql", "n8n"],
    "deployment": "bare-metal",
    "platform": "linux/amd64"
  }'
Generates hybrid stack with native install scripts for supported services.

With Authentication

curl -X POST http://localhost:3456/v1/generate \
  -H "Content-Type: application/json" \
  -H "X-API-Key: sk_live_abc123" \
  -d '{"projectName": "stack", "services": ["redis"]}'

Error Responses

Validation Error (400)

Invalid request body:
{
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Invalid generation input",
    "details": [
      {
        "field": "projectName",
        "message": "Required"
      },
      {
        "field": "services",
        "message": "Expected array, received string"
      }
    ]
  }
}

Conflict Error (409)

Incompatible services or configuration:
{
  "error": {
    "code": "CONFLICT_ERROR",
    "message": "Cannot use redis and valkey together: they conflict on port 6379"
  }
}

Generation Error (500)

Internal generation failure:
{
  "error": {
    "code": "GENERATION_ERROR",
    "message": "Failed to generate docker-compose.yml: invalid service configuration"
  }
}

Unauthorized (401)

{
  "error": {
    "code": "UNAUTHORIZED",
    "message": "Invalid API key."
  }
}

Use Cases

CI/CD Pipeline

Generate stacks in automation:
#!/bin/bash
# generate-stack.sh

curl -X POST http://localhost:3456/v1/generate?format=zip \
  -H "Content-Type: application/json" \
  -H "X-API-Key: $API_KEY" \
  -d "$(cat stack-config.json)" \
  --output stack.zip

unzip stack.zip
cd stack
docker compose up -d

Web Application

Build a stack generator UI:
async function generateStack(config) {
  const response = await fetch('http://localhost:3456/v1/generate', {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Accept': 'application/zip'
    },
    body: JSON.stringify(config)
  });
  
  if (!response.ok) {
    const error = await response.json();
    throw new Error(error.error.message);
  }
  
  const blob = await response.blob();
  const url = URL.createObjectURL(blob);
  
  // Trigger download
  const a = document.createElement('a');
  a.href = url;
  a.download = `${config.projectName}.zip`;
  a.click();
}

// Usage
generateStack({
  projectName: 'my-stack',
  services: ['postgresql', 'redis', 'n8n'],
  proxy: 'caddy',
  domain: 'example.com'
});

Import/Export Stacks

Export complete configuration for sharing:
# Export
curl -X POST "http://localhost:3456/v1/generate?format=complete" \
  -H "Content-Type: application/json" \
  -d "$(cat my-config.json)" > exported-stack.json

# Import (extract input and re-generate)
jq '.input' exported-stack.json | \
  curl -X POST http://localhost:3456/v1/generate \
    -H "Content-Type: application/json" \
    -d @-

Rate Limits

The generate endpoint has stricter rate limits:
  • Unauthenticated: 10 requests per 15 minutes
  • Authenticated: 50 requests per 15 minutes

Next Steps

Validate Endpoint

Validate configurations before generation

Services Endpoint

Browse available services to include

Build docs developers (and LLMs) love