Files
claude-foundations/platformhub/api-reference.md
Paul O'Reilly 6c0f2db169 Add Octopus Deploy Platform Hub knowledge base
New files:
- PLATFORMHUB.md: index for Platform Hub guidance
- platformhub/architecture.md: Git→PlatformHub→Projects model
- platformhub/ocl-syntax.md: complete OCL reference for templates
- platformhub/process-template-patterns.md: 5 proven patterns
- platformhub/gotchas.md: every error hit and how to fix it
- platformhub/api-reference.md: API vs UI capabilities
- best-practices/octopus-process-templates.md: consolidated best practices

Learned from building PlatformHub-Demo (30 microservices, 3 clouds).
Key discoveries: step templates are space-scoped (can't cross-reference),
worker_pool parameter is mandatory, publishing/sharing is UI-only.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 09:54:09 +13:00

5.4 KiB

Platform Hub API Reference

What can and cannot be managed via the Octopus Deploy API versus the UI.

API-Manageable Resources

These can be created, read, updated, and deleted via the REST API:

Resource Endpoint Notes
Spaces POST /api/spaces Requires SpaceManagersTeamMembers
Environments POST /api/{SpaceId}/environments
Lifecycles POST /api/{SpaceId}/lifecycles Include phase definitions
Project Groups POST /api/{SpaceId}/projectgroups
Docker Feeds POST /api/{SpaceId}/feeds FeedType: "Docker"
Step Templates POST /api/{SpaceId}/actiontemplates Space-scoped
Projects POST /api/{SpaceId}/projects
Channels POST /api/{SpaceId}/channels With lifecycle assignment
Releases POST /api/{SpaceId}/releases With channel and package selection
Runbooks POST /api/{SpaceId}/runbooks
Deployment Processes GET/PUT /api/{SpaceId}/deploymentprocesses/{id}
Variables GET/PUT /api/{SpaceId}/variables/{id}

UI-Only Operations

These cannot be done via API or CLI — must use the Octopus web UI:

Operation Why
Publish process template (create version) Platform Hub feature, no API endpoint
Share process template with spaces Platform Hub feature, no API endpoint
Configure Platform Hub Git connection Instance-level setting
Convert project to Config as Code POST .../git/convert exists but requires Git credentials interactively

Common API Patterns

Authentication

All API calls require the X-Octopus-ApiKey header:

API_KEY=$(grep 'value:' ~/dev/claude/secrets/taniwha.octopus.app/api_key | awk '{print $2}')
curl -s -H "X-Octopus-ApiKey: $API_KEY" \
  "https://taniwha.octopus.app/api/Spaces-103/environments"

Create a Space

curl -s -H "X-Octopus-ApiKey: $API_KEY" \
  -H "Content-Type: application/json" \
  -X POST "https://taniwha.octopus.app/api/spaces" \
  -d '{
    "Name": "My Space",
    "SpaceManagersTeamMembers": ["Users-21"],
    "IsDefault": false
  }'

Note: SpaceManagersTeamMembers must not be empty — at least one user or team required.

Create Environments

for env in Development Staging Production; do
  curl -s -H "X-Octopus-ApiKey: $API_KEY" \
    -H "Content-Type: application/json" \
    -X POST "https://taniwha.octopus.app/api/$SPACE_ID/environments" \
    -d "{\"Name\": \"$env\"}"
done

Create Lifecycles with Auto-Deploy Phases

# Non-Prod: Dev → Staging (auto-deploy both)
curl -s -H "X-Octopus-ApiKey: $API_KEY" \
  -H "Content-Type: application/json" \
  -X POST "https://taniwha.octopus.app/api/$SPACE_ID/lifecycles" \
  -d '{
    "Name": "Non-Prod",
    "Phases": [
      {
        "Name": "Development",
        "AutomaticDeploymentTargets": ["Environments-104"],
        "OptionalDeploymentTargets": [],
        "MinimumEnvironmentsBeforePromotion": 0,
        "IsOptionalPhase": false
      },
      {
        "Name": "Staging",
        "AutomaticDeploymentTargets": ["Environments-105"],
        "OptionalDeploymentTargets": [],
        "MinimumEnvironmentsBeforePromotion": 0,
        "IsOptionalPhase": false
      }
    ]
  }'

Create Docker Feed (GHCR)

curl -s -H "X-Octopus-ApiKey: $API_KEY" \
  -H "Content-Type: application/json" \
  -X POST "https://taniwha.octopus.app/api/$SPACE_ID/feeds" \
  -d '{
    "FeedType": "Docker",
    "Name": "GHCR Non-Prod",
    "FeedUri": "https://ghcr.io"
  }'

Create Step Template (Action Template)

curl -s -H "X-Octopus-ApiKey: $API_KEY" \
  -H "Content-Type: application/json" \
  -X POST "https://taniwha.octopus.app/api/$SPACE_ID/actiontemplates" \
  -d '{
    "Name": "Run Unit Tests",
    "Description": "Language-specific unit test suite",
    "ActionType": "Octopus.Script",
    "Properties": {
      "Octopus.Action.Script.ScriptSource": "Inline",
      "Octopus.Action.Script.Syntax": "PowerShell",
      "Octopus.Action.Script.ScriptBody": "Write-Host \"Running tests...\""
    },
    "Parameters": [
      {
        "Name": "Language",
        "Label": "Programming Language",
        "DefaultValue": "go",
        "DisplaySettings": {
          "Octopus.ControlType": "SingleLineText"
        }
      }
    ]
  }'

Create Release via API (CI-driven)

curl -s -X POST \
  -H "X-Octopus-ApiKey: $API_KEY" \
  -H "Content-Type: application/json" \
  "https://taniwha.octopus.app/api/$SPACE_ID/releases" \
  -d '{
    "ProjectId": "Projects-XXX",
    "ChannelId": "Channels-XXX",
    "Version": "1.2.3+202603251530",
    "SelectedPackages": [{
      "ActionName": "Deploy Non-Prod Image",
      "PackageReferenceName": "service-image",
      "Version": "1.2.3+202603251530"
    }]
  }'

Idempotent Script Pattern

For automation scripts that may be re-run:

# Check if resource exists before creating
existing=$(curl -s -H "X-Octopus-ApiKey: $API_KEY" \
  "https://taniwha.octopus.app/api/$SPACE_ID/projectgroups?take=100" \
  | python3 -c "
import sys, json
name = sys.argv[1]
for item in json.load(sys.stdin).get('Items', []):
    if item['Name'] == name:
        print(item['Id'])
        break
" "Marketplace" 2>/dev/null || echo "")

if [[ -n "$existing" ]]; then
  echo "Already exists: $existing"
else
  # Create it
  curl -s -X POST ...
fi

References