Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.crewship.ai/llms.txt

Use this file to discover all available pages before exploring further.

Provisioning

Endpoints that drive the Devcontainers pipeline: discover available features and runtimes, trigger or rebuild a crew’s cached image, and inspect the local cache. All routes require auth and are workspace-scoped where they touch crew rows. Implementation lives in internal/api/crew_provisioning_jobs.go and internal/api/crew_provisioning_cache.go; the underlying provisioner is in internal/devcontainer/.

Catalogs

Feature catalog

GET /api/v1/features/catalog?search=…
Lists devcontainer features Crewship can install. The dynamic fetcher pulls from upstream registries (ghcr.io/devcontainers/features/*, ghcr.io/devcontainers-extra/features/*, ghcr.io/crewship-ai/features/*); when that fails, the handler falls back to internal/devcontainer.FallbackCatalog so the UI is never empty. ?search= filters by name, description, or category (server-side substring). Response: 200 OK
{
  "features": [
    {
      "ref": "ghcr.io/devcontainers/features/python:1",
      "name": "Python",
      "description": "Installs the specified Python version, pip, and pipx. Supports virtual environments.",
      "category": "languages",
      "icon": "code",
      "size_hint": "~80 MB"
    }
  ]
}
FieldDescription
refOCI reference — what you put in devcontainer_config.features.
categoryOne of languages, tools, cloud, databases.
iconLucide icon name for UI rendering.
size_hintApproximate installed-size delta (~80 MB).
Unknown publishers (anything outside the three allowlisted prefixes) are rejected at provisioning time even if they appear in a custom catalog — see internal/devcontainer/features.go.

Runtime catalog

GET /api/v1/runtimes/catalog?search=…
Lists the mise-managed runtimes (Node, Python, Go, Terraform, kubectl, …) the workspace can pin in devcontainer_config.mise. Falls back to FallbackRuntimeCatalog when the dynamic fetcher fails. Not a base-image catalog. The base-image list is CLI-onlycrewship features base-images reads baseImagesCatalog directly from cmd/crewship/cmd_features.go; there is no HTTP endpoint for it today. Response: 200 OK
{
  "runtimes": [
    {
      "name": "Node.js",
      "tool": "node",
      "description": "JavaScript runtime.",
      "category": "languages",
      "icon": "hexagon",
      "versions": ["22", "20", "18"],
      "default_version": "22",
      "backends": ["asdf"]
    }
  ]
}
FieldDescription
toolMise tool ID — what you put in mise.json.
categorySame set as the feature catalog: languages, tools, cloud, databases.
versionsAvailable versions, ordered newest-first. May be empty when mise resolves dynamically.
default_versionWhat Crewship picks when the crew config does not pin one.
backendsMise install backends (asdf, cargo, npm, pipx, github). Empty → mise default.

Crew provisioning lifecycle

Provision status

GET /api/v1/crews/{crewId}/provision
Response: 200 OK. Always-present fields come from the crews row; the step / total / message / steps / log_tail / started_at / completed_at / error fields appear only when an in-memory job is currently running or recently finished for this crew.
{
  "status": "running",
  "devcontainer_config": "{\"image\":\"\",\"features\":{…}}",
  "cached_image": null,
  "config_hash": "a1b2c3d4e5f6…",
  "agents_pending_restart": 0,
  "step": 3,
  "total": 6,
  "message": "installing devcontainer features",
  "steps": ["validate", "pull-base", "install-features", "install-mise", "snapshot", "tag"],
  "log_tail": ["Feature python installed", "Feature node installed"],
  "started_at": "2026-04-30T11:01:18Z"
}
status is one of:
ValueMeaning
idleNo active job and no cached_image — crew has nothing built or in flight.
pendingJob enqueued, not yet picked up.
runningProvisioner is mid-pipeline.
completedCached image exists at cached_image (no active job).
failedJob ended in failure. error carries the reason.
FieldWhen presentMeaning
devcontainer_configalwaysRaw JSON blob pulled from crews.devcontainer_config (or null).
cached_imagealwaysLast successfully committed cache tag, or null.
config_hashalwaysSHA-256 of (base, devcontainer, mise) used as the cache key.
agents_pending_restartalwaysCount of crew agents whose live container is on a stale image.
step / totalactive jobNumeric progress (e.g. 3 / 6). The UI’s CrewProvisioningCard renders a checklist from this pair.
messageactive jobFree-form short message for the current step.
stepsactive jobOrdered list of step labels for the whole pipeline.
log_tailactive jobTrailing log lines (bounded) for inline display.
started_atactive jobRFC3339 start time.
completed_atfinished jobRFC3339 end time (only after completed/failed).
errorfailed jobHuman-readable failure reason.

Trigger provision

POST /api/v1/crews/{crewId}/provision
Requires the create role action (OWNER, ADMIN, MANAGER). Returns 202 immediately and runs the pipeline in a background goroutine; poll the status endpoint for progress. Response: 202 Accepted
{
  "status": "started",
  "message": "Provisioning started. Monitor with 'crewship crew provision status <slug>'."
}
Errors (RFC 7807 Problem Details on every 4xx/5xx — type, title, status, detail, instance):
StatusCondition
400Invalid crew ID, or crew has no devcontainer_config.
403Caller lacks create permission.
404Crew not in workspace.
409A provisioning job is already in progress for this crew. The 409 body extends Problem Details with job_status (the existing job’s state) so callers can decide whether to wait or fall through. Not idempotent — the second caller is told to back off, not silently joined to the running job.
429Per-workspace rate limit exceeded.
500Unexpected server-side error (panic-recovered).
503Provisioner not configured (no Docker client wired).

Rebuild

POST /api/v1/crews/{crewId}/rebuild
Clears the cached image marker on the crew row and triggers a fresh provision. Use when upstream features publish breaking updates under the same tag. Response: 202 Accepted — same shape as Trigger.

Restart agents

POST /api/v1/crews/{crewId}/restart-agents
Stops and re-execs every agent in the crew without rebuilding the container. Used when an env-var change should take effect without the cost of a new image. Returns 200 OK with { restarted: <count> }.

Cache image registry

List cached images

GET /api/v1/cache/images
Response: 200 OK
{
  "images": [
    {
      "tag": "crewship-cache:a1b2c3d4e5f6",
      "config_hash": "a1b2c3d4e5f6…",
      "created_at": "2026-04-29T18:22:01Z",
      "size_bytes": 824_191_022,
      "referenced_by_crew_ids": ["crw_backend"]
    }
  ]
}
Images orphaned from any crew (i.e. referenced_by_crew_ids is empty) are eligible for the GC sweeper. See CREWSHIP_CACHE_GC_AUTODELETE.

Delete cached image

DELETE /api/v1/cache/images/{tag}
Removes a cached image. Refuses to delete an image still referenced by a crew (returns 409 with the offending crew_ids). For force-delete, clear the crew’s cached_image first via POST /api/v1/crews/{crewId}/rebuild. Response: 204 No Content on success, 409 Conflict if referenced.

Tenancy

  • crewId and any tag referenced by a crew row are validated via crewBelongsToWorkspace. Cross-tenant lookups return 404.
  • The cache image registry is per-host, not per-workspace — operators sharing a Docker daemon will see each other’s tags. The referenced_by_crew_ids field is workspace-scoped, however, so leakage stops at the tag level.