Skip to content
GantryCD

Automation

Everything you can do in the UI goes through the same HTTP API, so anything can be scripted. There are three ways to reach it, all sharing one auth model.

Authentication: tokens

Outside a browser session you authenticate with a personal access token (PAT) for yourself, or a service account token for automation.

  • Create a PAT in the UI under your account settings. It’s bound to one user and one organization and shown once.
  • For unattended automation, prefer a service account token — it isn’t tied to a person who might leave.

Tokens go in the Authorization header:

curl -H "Authorization: Bearer gantrycd_pat_…" \
  https://gantrycd.example.com/api/v1/orgs/$ORG/stacks

The CLI: gantrycli

gantrycli is the command-line client. It covers the common objects:

gantrycli stacks list --org $ORG
gantrycli stacks sync --org $ORG --stack my-stack
gantrycli deployments create --org $ORG --stack my-stack --mode plan
gantrycli runner-groups list --org $ORG
gantrycli whoami

It reads its endpoint and token from configuration/environment so you don’t repeat them. There’s also an operator subtree for host-level maintenance (like promoting the first super-admin) that talks to the database directly — see Install.

Most commands accept --output json for a machine-readable result instead of the default text table:

gantrycli stacks list --org $ORG --output json | jq '.stacks[].id'

Every command and flag is listed in the CLI reference, which is generated from the CLI itself (make docs_cli) so it can’t drift.

Exit codes

0 always means success. On failure, most commands use one shared mapping derived from the error itself:

CodeMeaning
1Generic — anything not covered below
4Auth — the request was unauthorized or forbidden
5Not found
6Invalid — bad input or a conflict with existing state

deployments wait, deployments watch, deployments create --wait/--follow, and local-plan --wait/--follow use a different, more specific scheme for the deployment’s own terminal status, since that’s usually what a CI script actually wants to branch on — a poll-time error (an expired token, a typo’d ID) still uses the shared mapping above:

CodeOutcome
0Deployment finished
1Deployment failed
2Deployment cancelled
3Deployment skipped

Pass --log-format json (or set $GANTRYCD_LOG_FORMAT=json) to get the final error as a structured JSON line on stderr instead of plain text, for log pipelines that parse it.

The Go SDK

pkg/sdk is the official Go client. The CLI and the Terraform provider are both built on it, so it’s the most complete surface.

client, err := sdk.New(sdk.Options{
    BaseURL: "https://gantrycd.example.com",
    Token:   os.Getenv("GANTRYCD_PAT"),
})
if err != nil { /* ... */ }

stacks, err := client.Stacks.List(ctx, orgID)

The SDK is deliberately policy-free: it doesn’t read env vars or config files — the caller supplies the base URL and token. Errors from the backend come back as a typed *APIError; branch on them with sdk.IsNotFound, sdk.IsConflict, sdk.IsForbidden, and friends rather than matching strings.

The Terraform provider

Because GantryCD’s own objects (stacks, runner groups, cloud integrations, …) are just API resources, there’s a Terraform provider for managing GantryCD itself as code — so your stacks, contexts, and runner groups can live in OpenTofu next to the infrastructure they deploy.