Docs API

Sites and environments

Read and manage sites, their production and staging environments, files, domains, admin tools, stats, performance samples and logs.

A site in CaptainCore is a row in captaincore_sites plus one or more rows in captaincore_environments, typically Production and Staging. Almost everything on this page is scoped to the accounts you belong to.

Remember the casing rule: path segments want lowercase production or staging, while POST /sites/cli and the settings routes want capitalized Production, Staging or Both.

Sites

Method Path Notes
GET /sites Every site you can access, sorted by name
GET /sites/{site_id} or /sites/{slug} Full site object
GET /sites/{site_id}/details Site plus account, linked domains and shares
POST /sites/fetch Several sites at once, post_ids array or post_id
POST /sites Create a site (administrator)
POST /sites/{site_id} Patch site details
DELETE /sites/{site_id} Mark inactive
PUT /sites/update Bulk update (administrator)
PUT /sites/{site_id}/identity Change name and slug (administrator)
PUT /sites/{site_id}/accounts Reassign accounts (administrator)
POST /sites/{site_id}/remote-sync Re-read connection details from the provider (administrator)

GET /sites returns lightweight listing records. Auth tokens, the raw details blob and status are stripped.

curl -u user:app-password https://your-manager.example.com/wp-json/captaincore/v1/sites
[
  {
    "site_id": 135,
    "account_id": 12,
    "customer_id": 12,
    "name": "example.com",
    "site": "example",
    "provider": "kinsta",
    "core": "6.9.1",
    "home_url": "https://example.com",
    "storage": 123456789,
    "visits": 15000,
    "removed": false,
    "environments": [
      { "environment_id": 3365, "environment": "Production", "home_url": "https://example.com", "core": "6.9.1" }
    ]
  }
]

GET /sites/{site_id} accepts either the numeric id or the slug, and the same handler serves both. It is heavier than /details, which is what the site overview screen actually loads.

Creating a site takes a site object with name, site, account_id, provider and at least a Production entry in environments. Optional keys include customer_id, provider_id, provider_site_id and shared_with.

POST /sites/{site_id} merges the keys you send into the stored site details. Non-administrators may only write details.removed: sending true emails a removal request and logs it, false cancels it.

Environments

Method Path Notes
GET /sites/{site_id}/environments Environments on one site
GET /environments Every environment you can reach, source_environment_id excludes one
POST /sites/{site_id}/environments Add an environment (administrator)
POST /sites/{site_id}/environments/connect Link an existing remote staging environment (administrator)
PUT, DELETE /sites/{site_id}/environments/{environment_id} Edit or remove connection settings (administrator)
PUT /sites/{site_id}/settings Managed-update settings
POST /sites/{site_id}/{environment}/monitor Uptime monitor, monitor is 1 or 0
POST /sites/{site_id}/{environment}/captures Capture pages and optional basic auth
POST /sites/{site_id}/backup Backup schedule, settings.active, interval, mode
GET /sites/{site_id}/{environment}/sync/data Trigger a data sync
GET /sites/{site_id}/{environment}/captures/new Trigger fresh captures
GET /sites/{site_id}/environments/{environment_id}/push-targets Where this environment can be pushed
POST /sites/environments/push Push one environment onto another

PUT /sites/{site_id}/settings takes environment (the database name, so Production or Staging) and a value object with updates_enabled, plus optional updates_exclude_themes and updates_exclude_plugins arrays of slugs.

curl -X POST -u user:app-password \
  -H "Content-Type: application/json" \
  -d '{"source_environment_id": 3365, "target_environment_id": 3366}' \
  https://your-manager.example.com/wp-json/captaincore/v1/sites/environments/push

Files

Method Path Notes
GET /environment/{environment_id}/files path relative to home, default the home root; action is list (default) or view
DELETE /environment/{environment_id}/files path required, query or body

Both viewing and deleting a file are recorded in the activity log with the path and environment.

curl -u user:app-password \
  "https://your-manager.example.com/wp-json/captaincore/v1/environment/3365/files?path=wp-content&action=list"

Site domains

These are hostnames attached to a hosting environment at the provider, not registrar records. For registrar and DNS work see Domains, DNS and accounts.

Method Path Notes
GET /sites/{site_id}/{environment}/domains List hostnames on the environment
POST /sites/{site_id}/{environment}/domains Add one, domain_name required, is_wildcardless optional
DELETE /sites/{site_id}/{environment}/domains domain_ids array of provider domain ids
PUT /sites/{site_id}/{environment}/domains/primary domain_id, plus run_search_and_replace (defaults true)
POST /sites/{site_id}/{environment}/domains/verify Ask the provider to verify
POST /providers/kinsta/check-verification Poll Kinsta verification state

Admin tools

Method Path Notes
GET /sites/{site_id}/{environment}/magiclogin One-time admin login link
GET /sites/{site_id}/{environment}/magiclogin/{wp_user_id} Login as a specific WordPress user
GET /sites/{site_id}/{environment}/phpmyadmin phpMyAdmin access, provider dependent
GET /sites/{site_id}/users Cached WordPress users
GET /sites/{site_id}/timeline Site timeline, process log notes and events
GET /sites/{site_id}/usage-breakdown Storage and visit breakdown
GET /sites/{site_id}/update-logs Update history for this site
POST /sites/{site_id}/invite Invite someone to the site’s customer account
GET /sites/{site_id}/invite-preview Preview that invite
POST /sites/{site_id}/grant-access Grant an existing user access
curl -u user:app-password \
  https://your-manager.example.com/wp-json/captaincore/v1/sites/135/production/magiclogin

Stats

Site analytics come from Fathom. The integration needs a fathom provider row with an api_key credential.

Method Path Key parameters
GET /sites/{site_id}/stats from_at, to_at, grouping (hour, day, month, year), environment, fathom_id
GET /sites/{site_id}/stats/top-pages from_at, to_at, environment, limit (default 10)
GET /sites/{site_id}/stats/top-referrers Same shape as top pages
POST /sites/{site_id}/stats/share fathom_id, sharing (none, private, public), share_password
POST /site/{site_id}/analytics Legacy analytics fetch
PUT /sites/{site_id}/fathom Set the tracker id (administrator)
curl -u user:app-password \
  "https://your-manager.example.com/wp-json/captaincore/v1/sites/135/stats?from_at=2026-08-01&to_at=2026-08-31&grouping=day"

Performance

Method Path Notes
POST /sites/{site_id}/{environment}/performance-monitor enabled true or false
GET /sites/{site_id}/{environment}/performance-monitor hours lookback (omit or 0 for everything), format=raw for the sample series
curl -u user:app-password \
  "https://your-manager.example.com/wp-json/captaincore/v1/sites/135/production/performance-monitor?hours=24&format=raw"

Logs

Live logs are read over SSH. Archived logs come from the provider’s rotation, and are on the older singular /site/ prefix.

Method Path Notes
GET /sites/{site_id}/{environment}/logs List available log files
POST /sites/{site_id}/{environment}/logs/fetch file from the list, restricted to A-Z a-z 0-9 . _ / -; limit lines, default 1000
GET /site/{site_id}/{environment}/logs-archive List archived logs
GET /site/{site_id}/{environment}/logs-archive/download file must match ^(access|error)\.log-\d{4}-\d{2}-\d{2}-\d+(\.gz)?$
GET /site/{site_id}/{environment}/logs-archive/view Same file pattern, plus lines between 1 and 5000, default 1000
curl -X POST -u user:app-password \
  -H "Content-Type: application/json" \
  -d '{"file":"error.log","limit":200}' \
  https://your-manager.example.com/wp-json/captaincore/v1/sites/135/production/logs/fetch

Backups, snapshots and captures

Method Path Notes
GET /site/{site_id}/{environment}/backups Restic snapshot list
GET /sites/{site_id}/{environment}/backups/{backup_id} One backup, with a file query (base64url path) to preview a file
GET /site/{site_id}/snapshots Downloadable snapshots
GET /sites/{site_id}/snapshot-link/{snapshot_id} Signed download link
GET /site/{site_id}/snapshots/{snapshot_id}-{token}/{name} Public, token protected download
GET /site/{site_id}/{environment}/captures Visual capture history

Quicksaves, the daily git history of themes, plugins and core, live on their own routes: /quicksaves, /quicksaves/search, /quicksaves/{hash}, /quicksaves/{hash}/changed, /quicksaves/{hash}/filediff, /quicksaves/{hash}/rollback and /quicksaves/{hash}/sandbox-token. They are served straight from the CLI rather than a Manager table.

Filters

Filters answer “which of my sites run this plugin or theme”.

Method Path Notes
POST /filters/sites Filter by component, version, status and core
GET /site-filters Available filter options
GET /filters/{name}/versions/ Versions seen for a slug
GET /filters/{name}/statuses/ Statuses seen for a slug
GET /wp-plugins, /wp-themes Search the wordpress.org directories

The full route list, including the administrator-only variants, is in the Endpoint index.